NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

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:

Android fragmenty

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é labelData01labelData04. 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

 

Předchozí článek
Android fragmenty - Vytvoření prvního fragmentu
Všechny články v sekci
Android fragmenty
Přeskočit článek
(nedoporučujeme)
Kvíz - Tvorba fragmentu v Androidu
Článek pro vás napsal Pavel
Avatar
Uživatelské hodnocení:
6 hlasů
Autor se věnuje programování v Javě, hlavně pro Android. Mezi jeho další zájmy patří Arduino, Minecraft.
Aktivity