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
publicmetodám a proměnným fragmentu, - fragment přistupuje k
publicmetodá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é labelData01až
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 12x (3.7 MB)
Aplikace je včetně zdrojových kódů v jazyce Java


