3. diel - Android fragmenty - Odovzdanie dát fragmentu
V minulej lekcii, Android fragmenty - Vytvorenie prvého fragmentu , sme vytvorili novú aktivitu, v ktorej sme
zobrazili náš prvý fragment FirstFragment
.
V dnešnom Android tutoriále zahájime výklad o komunikácii medzi fragmentom a aktivitou. Ukážeme si odovzdanie dát fragmentu.
Už vieme, že fragment je vždy súčasťou nejakej aktivity. Tiež vieme, že programovo pridávané fragmenty zobrazujeme vo vopred pripravenom layoutu, ktorému hovoríme kontajner. Je možné vložený fragment do nejakej aktivity zvonku ďalej ovplyvňovať? Existuje nejaký spôsob komunikácie medzi fragmentom a jeho materskou aktivitou?
Komunikácia medzi fragmentom a aktivitou
Vytvorený fragment je možné prostredníctvom jeho aktivity ovplyvňovať alebo meniť jeho obsah. K tejto komunikácii medzi aktivitou a fragmentom môže dochádzať týmito spôsobmi:- odovzdaním parametrov fragmentu,
- aktivita pristupuje k
public
metódam a premenným fragmentu, - fragment pristupuje k
public
metódam a premenným aktivity, - komunikácia pomocou rozhrania.
Z vyššie uvedeného teda vyplýva, že komunikácia môže byť obojsmerná.
Odovzdanie parametrov fragmentu
Fragmentu, pred jeho pridaním do aktivity, môžeme priradiť balíček s dátami. Tieto dáta sú reprezentované objektom typuBundle
. V takom objekte sú jednotlivé hodnoty uložené pod
kľúčmi, tvorenými textovými reťazcami.
Do objektu typu Bundle
je možné vložiť
primitívne dátové typy a ich polia a tiež iný objekt typu
Bundle
.
Odovzdávanie vstupných dát fragmentu si prakticky ukážeme na našom
prvom dokončenom fragmente FirstFragment
. Za týmto účelom
upravíme náš ukážkový projekt. Pred vytvorením
transakcie, zobrazujúcej fragment v aktivite, vytvoríme objekt typu
Bundle
. Tento objekt potom naplníme potrebnými dátami.
V našej ukážke budú dáta tvorené jedným číslom typu
int
, jedným číslom typu float
, jedným textovým
reťazcom a jednou hodnotou typu boolean
. Tento balík údajov
fragmentu pribalíme na cestu volaním metódy setArguments()
na
jeho konkrétnu inštanciu. Až potom pripravenú transakciu potvrdíme volaním
metódy commit()
. Tieto dáta neskôr môžeme kdekoľvek v Java
kóde fragmentu vyzdvihnúť volaním metódy getArguments()
.
Fragmenty
FirstFragment
a ActivityFirstFragment
Najprv upravíme XML kód a Java kód
fragmentu FirstFragment
. Potom zmeníme metódu
showFirstFragment()
aktivity ActivityFirstFragment
.
Úprava XML kódu fragmentu
FirstFragment
Do súboru first_fragment.xml
pridáme päť elementov
TextView
, pridanými na koniec XML kódu, takto:
<!-- * ... --> <TextView android:id="@+id/textView2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Dáta prijaté 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" />
Ak teraz aplikáciu spustíme a zobrazíme náš prvý fragment, uvidíme:
Fragment zatiaľ žiadne dáta nezobrazuje. Musíme totiž najprv upraviť
kód v súbore FirstFragment.java
.
Úprava Java kódu fragmentu
FirstFragment
Do triedy FirstFragment
si teraz pridáme nové
premenné a metódu
onCreateView()
.
Premenné
Najprv pridáme štyri premenné pre uloženie referencií novo pridanýchTextView
. Ďalšou novou premennou bude premenná
data
typu Bundle
. Tá bude slúžiť na uloženie
prichádzajúcich dát:
public class FirstFragment extends Fragment { //... TextView labelData01; TextView labelData02; TextView labelData03; TextView labelData04; Bundle data; //... }
Metóda onCreateView()
Prepísanú metódu 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áš prvý 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); // Príjem dát z materskej aktivity data = getArguments(); // // Zobrazenie prijatých dát 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; }
Najprv inicializujeme premenné labelData01
až
labelData04
. Následne voláme metódu getArguments()
,
čím do premenného data
uložíme prípadné prichádzajúce
dáta. Pokiaľ nie sú žiadne prichádzajúce dáta k dispozícii, bude
metódou getArguments()
vrátená hodnota null
.
Pokiaľ premenné data
nie je null
, nastavíme texty
príslušných TextView
pomocou metódy setText()
.
Úprava Java kódu
aktivity ActivityFirstFragment
V triede ActivityFirstFragment
upravíme metódu
showFirstFragment()
do tejto podoby:
private void showFirstFragment() { Bundle args = new Bundle(); args.putInt("key_int", 6156); args.putFloat("key_float", 23.789f); args.putString("key_string", "Textový reťazec"); 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(); }
Pred vykonaním transakcie pridanie fragmentu do kontajnera deklarujeme
premennú args
typu Bundle
. Tú následne plníme
dátami, ktoré chceme odovzdať zobrazovanému fragmentu. Balíček s dátami
fragmentu odovzdáme metódou setArguments()
.
Týmto máme dokončenú ukážku s odovzdaním dát fragmentu. Na záver si popíšeme problematiku potrebnú na ďalší výklad o komunikácii aktivity s fragmentom.
Vyhľadanie vloženého fragmentu
Aby mohla aktivita s už vloženým fragmentom komunikovať, potrebujeme byť schopní ho nejakým spôsobom identifikovať. Hovorili sme si, že pre správu fragmentov v aktivite slúži triedaFragmentManager
.
Spôsob práce s fragmentmi a kontajnerom si môžeme predstaviť ako manipuláciu s kôpkou kariet. Postupne ich skladáme na seba alebo ich jeden po druhom z kôpky odstraňujeme. V jednom kontajneri je vždy viditeľný len jeden fragment - ten na vrchole pomyselnej kôpky. Z uvedeného vyplýva, že v rámci jedného kontajnera môžeme pracovať s väčším počtom fragmentov. Preto potrebujeme byť schopní, v tejto pomyselnej kôpke fragmentov, nájsť konkrétny fragment podľa nejakého označenia.
Neplatí to, že by automaticky bolo pristupované k tomu fragmentu, ktorý
je na vrchole kôpky (je viditeľný). My totiž môžeme komunikovať aj s
fragmentmi, ktoré síce v kôpke sú, ale nie sú viditeľné (nie sú na
vrchole kôpky). Aby sme boli schopní konkrétny fragment v kontajneri neskôr
nájsť, je nutné ho nejako označiť. Na to slúži značka (tag) v podobe
textového reťazca. Tento tag vkladanému fragmentu pridelíme
v treťom parametri metódy add()
:
fragmentTransaction.add(R.id.containerForFirstFragment, myFragment, "my_tag");
Takto vložený fragment môžeme neskôr nájsť pomocou triedy
FragmentManager
a jej metódy findFragmentByTag()
takto:
FragmentManager fm = getSupportFragmentManager();
MyFragment fragment = (MyFragment) fm.findFragmentByTag("my_tag");
Metóda findFragmentByTag()
prijíma jeden parameter typu
String
, predstavujúci tag hľadaného fragmentu. Pokiaľ by nebol
takýto fragment nájdený, bude v premennej fragment
hodnota
null
. V opačnom prípade bude táto premenná obsahovať objekt
typu Fragment
. Pre získanie prístupu k nami deklarovaným
metódam a premenným nájdeného fragmentu je preto nutná typová
konverzia.
V budúcej časti, Android fragmenty - Java kód FragmentForCommunication , napíšeme Java kód fragmentu
FragmentForCommunication
, ktorý bude súčasťou príkladu
obojsmernej komunikácie medzi fragmentom a aktivitou.
Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.
Stiahnuť
Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami
Stiahnuté 11x (3.7 MB)
Aplikácia je vrátane zdrojových kódov v jazyku Java