IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

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 typu Bundle. 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:

Android fragmenty

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ých TextView. Ď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é labelData01labelData04. 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 trieda FragmentManager.

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

 

Predchádzajúci článok
Android fragmenty - Vytvorenie prvého fragmentu
Všetky články v sekcii
Android fragmenty
Preskočiť článok
(neodporúčame)
Android fragmenty - Java kód FragmentForCommunication
Článok pre vás napísal Pavel
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity