Lekce 3 - Android fragmenty - Předání dat fragmentu
V minulé lekci, Android fragmenty - Vytvoření prvního fragmentu, jsme vytvořili novou aktivitu, ve které jsme
zobrazili náš první fragment FirstFragment
.
V dnešním Android tutoriálu zahájíme výklad o komunikaci mezi fragmentem a aktivitou. Ukážeme si předání dat fragmentu.
Již víme, že fragment je vždy součástí nějaké aktivity. Také víme, že programově přidávané fragmenty zobrazujeme v předem připraveném layoutu, kterému říkáme kontejner. Lze vložený fragment do nějaké aktivity z venčí dále ovlivňovat? Existuje nějaký způsob komunikace mezi fragmentem a jeho mateřskou aktivitou?
Komunikace mezi fragmentem a aktivitou
Vytvořený fragment lze prostřednictvím jeho aktivity ovlivňovat nebo měnit jeho obsah. K této komunikaci mezi aktivitou a fragmentem může docházet těmito způsoby:
- předáním parametrů fragmentu,
- aktivita přistupuje k
public
metodám a proměnným fragmentu, - fragment přistupuje k
public
metodám a proměnným aktivity, - komunikace pomocí rozhraní.
Z výše uvedeného tedy vyplývá, že komunikace může být obousměrná.
Předání parametrů fragmentu
Fragmentu, před jeho přidáním do aktivity, můžeme
přiřadit balíček s daty. Tato data jsou reprezentována objektem typu
Bundle
. V takovém objektu jsou jednotlivé hodnoty uloženy pod
klíči, tvořenými textovými řetězci.
Do objektu typu Bundle
lze vložit primitivní
datové typy a jejich pole a také jiný objekt typu Bundle
.
Předávání vstupních dat fragmentu si prakticky ukážeme na našem
prvním dokončeném fragmentu FirstFragment
. Za tímto účelem
upravíme náš ukázkový projekt. Před vytvořením
transakce, zobrazující fragment v aktivitě, vytvoříme objekt typu
Bundle
. Tento objekt pak naplníme potřebnými daty.
V naší ukázce budou data tvořená jedním číslem typu int
,
jedním číslem typu float
, jedním textovým řetězcem a jednou
hodnotou typu boolean
. Tento balíček dat fragmentu přibalíme na
cestu voláním metody setArguments()
na jeho konkrétní instanci.
Teprve potom připravenou transakci potvrdíme voláním metody
commit()
. Tato data později můžeme kdekoliv v Java kódu
fragmentu vyzvednout voláním metody getArguments()
.
Fragmenty
FirstFragment
a ActivityFirstFragment
Nejprve upravíme XML kód a Java kód
fragmentu FirstFragment
. Poté změníme metodu
showFirstFragment()
aktivity
ActivityFirstFragment
.
Úprava XML kódu fragmentu
FirstFragment
Do souboru first_fragment.xml
přidáme pět elementů
TextView
, přidanými na konec XML kódu, takto:
<!-- * ... --> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Data přijatá z aktivity" android:textColor="@color/black" android:textSize="16sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView" /> <TextView android:id="@+id/labelData01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/textView2" /> <TextView android:id="@+id/labelData02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/labelData01" /> <TextView android:id="@+id/labelData03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="TextView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/labelData02" /> <TextView android:id="@+id/labelData04" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="TextView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/labelData03" />
Pokud nyní aplikaci spustíme a zobrazíme náš první fragment, uvidíme:
Fragment zatím žádná data nezobrazuje. Musíme totiž nejprve upravit
kód v souboru FirstFragment.java
.
Úprava Java kódu fragmentu
FirstFragment
Do třídy FirstFragment
si nyní přidáme nové
proměnné a metodu
onCreateView()
.
Proměnné
Nejprve přidáme čtyři proměnné pro uložení
referencí nově přidaných TextView
. Další
novou proměnnou bude proměnná data
typu Bundle
. Ta
bude sloužit k uložení příchozích dat:
public class FirstFragment extends Fragment { //... TextView labelData01; TextView labelData02; TextView labelData03; TextView labelData04; Bundle data; //... }
Metoda onCreateView()
Přepsanou metodu onCreateView()
si doprogramujeme takto:
@Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.first_fragment, container, false); label = view.findViewById(R.id.textView); label.setText("Toto je náš první fragment!"); labelData01 = view.findViewById(R.id.labelData01); labelData02 = view.findViewById(R.id.labelData02); labelData03 = view.findViewById(R.id.labelData03); labelData04 = view.findViewById(R.id.labelData04); // Příjem dat z mateřské aktivity data = getArguments(); // // Zobrazení přijatých dat if (data != null) { labelData01.setText("" + data.getInt("key_int", 0)); labelData02.setText("" + data.getFloat("key_float", 0)); labelData03.setText("" + data.getString("key_string", "NIC")); labelData04.setText("" + data.getBoolean("key_boolean", false)); } return view; }
Nejprve inicializujeme proměnné labelData01
až
labelData04
. Následně voláme metodu getArguments()
,
čímž do proměnné data
uložíme případná příchozí data.
Pokud nejsou žádná příchozí data k dispozici, bude metodou
getArguments()
vrácena hodnota null
. Pokud proměnná
data
není null
, nastavíme texty příslušných
TextView
pomocí metody setText()
.
Úprava Java kódu
aktivity ActivityFirstFragment
Ve třídě ActivityFirstFragment
upravíme metodu
showFirstFragment()
do této podoby:
private void showFirstFragment() { Bundle args = new Bundle(); args.putInt("key_int", 6156); args.putFloat("key_float", 23.789f); args.putString("key_string", "Textový řetězec"); args.putBoolean("key_boolean", true); FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); FirstFragment firstFragment = new FirstFragment(); firstFragment.setArguments(args); fragmentTransaction.add(R.id.containerForFirstFragment, firstFragment); fragmentTransaction.commit(); }
Před provedením transakce přidání fragmentu do kontejneru deklarujeme
proměnnou args
typu Bundle
. Tu následně plníme
daty, která chceme předat zobrazovanému fragmentu. Balíček s daty fragmentu
předáme metodou setArguments()
.
Tímto máme dokončenou ukázku s předáním dat fragmentu. Na závěr si popíšeme problematiku potřebnou k dalšímu výkladu o komunikaci aktivity s fragmentem.
Vyhledání vloženého fragmentu
Aby mohla aktivita s již vloženým fragmentem komunikovat,
potřebujeme být schopni jej nějakým způsobem
identifikovat. Říkali jsme si, že pro správu fragmentů v
aktivitě slouží třída FragmentManager
.
Způsob práce s fragmenty a kontejnerem si můžeme představit jako manipulaci s hromádkou karet. Postupně je skládáme na sebe nebo je jeden po druhém z hromádky odstraňujeme. V jednom kontejneru je vždy viditelný jen jeden fragment - ten na vrcholu pomyslné hromádky. Z uvedeného vyplývá, že v rámci jednoho kontejneru můžeme pracovat s větším počtem fragmentů. Proto potřebujeme být schopní, v této pomyslné hromádce fragmentů, najít konkrétní fragment podle nějakého označení.
Neplatí to, že by automaticky bylo přistupováno k tomu fragmentu, který
je na vrcholu hromádky (je viditelný). My totiž můžeme komunikovat i s
fragmenty, které sice v hromádce jsou, ale nejsou viditelné (nejsou na
vrcholu hromádky). Abychom byli schopní konkrétní fragment v kontejneru
později nalézt, je nutné jej nějak označit. K tomu slouží značka (tag) v
podobě textového řetězce. Tento tag vkládanému fragmentu
přidělíme ve třetím parametru metody add()
:
fragmentTransaction.add(R.id.containerForFirstFragment, myFragment, "my_tag");
Takto vložený fragment můžeme později nalézt pomocí třídy
FragmentManager
a její metody findFragmentByTag()
takto:
FragmentManager fm = getSupportFragmentManager();
MyFragment fragment = (MyFragment) fm.findFragmentByTag("my_tag");
Metoda findFragmentByTag()
přijímá jeden parametr typu
String
, představující tag hledaného fragmentu. Pokud by nebyl
takový fragment nalezen, bude v proměnné fragment
hodnota
null
. V opačném případě bude tato proměnná obsahovat objekt
typu Fragment
. Pro získání přístupu k námi deklarovaným
metodám a proměnným nalezeného fragmentu je proto nutná typová
konverze.
V následujícím kvízu, Kvíz - Tvorba fragmentu v Androidu, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 11x (3.7 MB)
Aplikace je včetně zdrojových kódů v jazyce Java