Sdílet prostřednictvím


ViewPager s fragmenty

ViewPager je správce rozložení, který umožňuje implementovat gestrální navigaci. Gesturalní navigace umožňuje uživateli procházet stránky dat potáhnutím prstem doleva a doprava. Tato příručka vysvětluje, jak implementovat potažením prstem použitelné uživatelské rozhraní pomocí ViewPageru pomocí fragmentů jako datových stránek.

Přehled

ViewPager se často používá ve spojení s fragmenty, aby bylo snazší spravovat životní cyklus každé stránky v souboru ViewPager. V tomto názorném postupu se používá k vytvoření aplikace s názvem FlashCardPager, ViewPager která představuje řadu matematických problémů na flash kartách. Každá flash karta se implementuje jako fragment. Uživatel potáhne prstem doleva a doprava přes flash karty a klepne na matematický problém, aby zobrazil odpověď. Tato aplikace vytvoří Fragment instanci pro každou flash kartu a implementuje adaptér odvozený z FragmentPagerAdapter. V viewpageru a zobrazeních se většina práce prováděla v MainActivity metodách životního cyklu. V FlashCardPageru bude většina práce provedena Fragment jednou z jeho metod životního cyklu.

Tato příručka se nezabývá základy fragmentů – pokud ještě neznáte fragmenty v Xamarin.Androidu, přečtěte si článek Fragmenty , které vám pomůžou začít s fragmenty.

Spuštění projektu aplikace

Vytvořte nový projekt Androidu s názvem FlashCardPager. Dále spusťte Správce balíčků NuGet (další informace o instalaci balíčků NuGet najdete v tématu Návod: Zahrnutí NuGetu do projektu). Vyhledejte a nainstalujte balíček Xamarin.Android.Support.v4 , jak je vysvětleno v viewpageru a zobrazeních.

Přidání ukázkového zdroje dat

Ve formátu FlashCardPager je zdrojem dat balíček flash karet reprezentovaných FlashCardDeck třídou; tento zdroj dat dodává ViewPager obsah položky. FlashCardDeck obsahuje připravenou kolekci matematických problémů a odpovědí. Konstruktor FlashCardDeck nevyžaduje žádné argumenty:

FlashCardDeck flashCards = new FlashCardDeck();

Kolekce flash karet je FlashCardDeck uspořádaná tak, aby každá flash karta byla přístupná indexerem. Například následující řádek kódu načte čtvrtý problém s flash kartou v balíčku:

string problem = flashCardDeck[3].Problem;

Tento řádek kódu načte odpovídající odpověď na předchozí problém:

string answer = flashCardDeck[3].Answer;

Vzhledem k tomu, že podrobnosti implementace FlashCardDeck nejsou relevantní pro pochopení ViewPager, FlashCardDeck kód zde není uvedený. Zdrojový kód, který má FlashCardDeck být k dispozici v FlashCardDeck.cs. Stáhněte si tento zdrojový soubor (nebo zkopírujte a vložte kód do nového souboru FlashCardDeck.cs ) a přidejte ho do projektu.

Vytvoření rozložení ViewPager

Otevřete Prostředky/layout/Main.axml a nahraďte jeho obsah následujícím kódem XML:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/viewpager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    </android.support.v4.view.ViewPager>

Tento KÓD XML definuje, ViewPager která zabírá celou obrazovku. Všimněte si, že musíte použít plně kvalifikovaný název android.support.v4.view.ViewPager , protože ViewPager je zabalený v knihovně podpory. ViewPager je k dispozici pouze z knihovny podpory androidu v4. Není k dispozici v sadě Android SDK.

Nastavení ViewPageru

Upravte MainActivity.cs a přidejte následující using příkazy:

using Android.Support.V4.View;
using Android.Support.V4.App;

MainActivity Změňte deklaraci třídy tak, aby byla odvozena zFragmentActivity:

public class MainActivity : FragmentActivity

MainActivity je odvozen zFragmentActivity (nikoli Activity) protože FragmentActivity ví, jak spravovat podporu fragmentů. Nahraďte metodu OnCreate následujícím kódem:

protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);
    SetContentView(Resource.Layout.Main);
    ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
    FlashCardDeck flashCards = new FlashCardDeck();
}

Tento kód provádí následující úkony:

  1. Nastaví zobrazení z prostředku rozložení Main.axml .

  2. Načte odkaz na ViewPager rozložení.

  3. Vytvoří instanci nového FlashCardDeck zdroje dat.

Když sestavíte a spustíte tento kód, měli byste vidět zobrazení, které se podobá následujícímu snímku obrazovky:

Snímek obrazovky s aplikací FlashCardPager s prázdným ViewPagerem

V tomto okamžiku ViewPager je prázdný, protože chybí fragmenty, které se používají, ViewPagera chybí adaptér pro vytváření těchto fragmentů z dat v FlashCardDeck.

V následujících částech se vytvoří funkce FlashCardFragment každé flash karty a vytvoří se pro FragmentPagerAdapter připojení ViewPager k fragmentům vytvořeným z dat v objektu FlashCardDeck.

Vytvoření fragmentu

Každá flash karta bude spravována fragmentem uživatelského rozhraní s názvem FlashCardFragment. FlashCardFragmentZobrazení zobrazí informace obsažené na jedné flash kartě. Každá instance FlashCardFragment bude hostitelem ViewPager. FlashCardFragmentZobrazení bude obsahovat TextView text problému s flash kartou. Toto zobrazení implementuje obslužnou rutinu události, která používá Toast k zobrazení odpovědi, když uživatel klepne na otázku flash karty.

Vytvoření rozložení FlashCardFragment

Před FlashCardFragment implementací musí být definováno jeho rozložení. Toto rozložení je fragmentem rozložení kontejneru pro jeden fragment. Přidejte nové rozložení Androidu do prostředků nebo rozložení s názvem flashcard_layout.axml. Otevřete Resources/layout/flashcard_layout.axml a nahraďte jeho obsah následujícím kódem:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:id="@+id/flash_card_question"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textAppearance="@android:style/TextAppearance.Large"
            android:textSize="100sp"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:text="Question goes here" />
    </RelativeLayout>

Toto rozložení definuje jeden fragment flash karty; každý fragment se skládá z TextView matematického problému s použitím velkého písma (100sp). Tento text je svisle a vodorovně na flash kartě zarovnaný na střed.

Vytvoření počáteční třídy FlashCardFragment

Přidejte nový soubor s názvem FlashCardFragment.cs a nahraďte jeho obsah následujícím kódem:

using System;
using Android.OS;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;

namespace FlashCardPager
{
    public class FlashCardFragment : Android.Support.V4.App.Fragment
    {
        public FlashCardFragment() { }

        public static FlashCardFragment newInstance(String question, String answer)
        {
            FlashCardFragment fragment = new FlashCardFragment();
            return fragment;
        }
        public override View OnCreateView (
            LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
        {
            View view = inflater.Inflate (Resource.Layout.flashcard_layout, container, false);
            TextView questionBox = (TextView)view.FindViewById (Resource.Id.flash_card_question);
            return view;
        }
    }
}

Tento kód zakryvuje základní Fragment definici, která se použije k zobrazení flash karty. Všimněte si, že FlashCardFragment je odvozena z verze Fragment knihovny podpory definované v Android.Support.V4.App.Fragment. Konstruktor je prázdný, newInstance aby se metoda továrny použila k vytvoření nového FlashCardFragment místo konstruktoru.

Metoda OnCreateView životního cyklu vytvoří a nakonfiguruje TextView. Nafoukne rozložení fragmentu TextView a vrátí nafouknutí TextView volajícímu. LayoutInflater a ViewGroup jsou předány OnCreateView tak, aby mohlo nafouknout rozložení. Sada savedInstanceState obsahuje data, která OnCreateView se používají k opětovnému TextView vytvoření z uloženého stavu.

Zobrazení fragmentu je explicitně nafouknuto voláním inflater.Inflate. Argument container je nadřazený zobrazení a false příznak dává pokyn, aby nedal nafukované zobrazení do nadřazeného zobrazení zobrazení (přidá se při ViewPager volání metody adaptéru GetItem později v tomto návodu).

Přidání stavových kódů do FlashCardFragment

Podobně jako aktivita má Bundle fragment hodnotu, kterou používá k uložení a načtení stavu. V souboru FlashCardPager se používá Bundle k uložení otázky a odpovědi na text přidružené flash karty. V FlashCardFragment.cs přidejte do horní části FlashCardFragment definice třídy následující Bundle klíče:

private static string FLASH_CARD_QUESTION = "card_question";
private static string FLASH_CARD_ANSWER = "card_answer";

Upravte metodu newInstance Bundle továrny tak, aby vytvořil objekt a pomocí výše uvedených klíčů uložte předanou otázku a text odpovědi do fragmentu po vytvoření instance:

public static FlashCardFragment newInstance(String question, String answer)
{
    FlashCardFragment fragment = new FlashCardFragment();

    Bundle args = new Bundle();
    args.PutString(FLASH_CARD_QUESTION, question);
    args.PutString(FLASH_CARD_ANSWER, answer);
    fragment.Arguments = args;

    return fragment;
}

Upravte metodu OnCreateView životního cyklu fragmentu, aby načetla tyto informace z předaného balíčku a načetla text otázky do TextBox:

public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
    string question = Arguments.GetString(FLASH_CARD_QUESTION, "");
    string answer = Arguments.GetString(FLASH_CARD_ANSWER, "");

    View view = inflater.Inflate(Resource.Layout.flashcard_layout, container, false);
    TextView questionBox = (TextView)view.FindViewById(Resource.Id.flash_card_question);
    questionBox.Text = question;

    return view;
}

Proměnná answer se zde nepoužívá, ale použije se později při přidání kódu obslužné rutiny události do tohoto souboru.

Vytvoření adaptéru

ViewPagerpoužívá objekt kontroleru adaptéru, který se nachází mezi ViewPager zdrojem dat a zdrojem dat (viz obrázek v článku Adaptér ViewPager). Chcete-li získat přístup k datům, ViewPager je nutné zadat vlastní adaptér odvozený z PagerAdapter. Vzhledem k tomu, že tento příklad používá fragmenty, používá – FragmentPagerAdapter FragmentPagerAdapter je odvozen z PagerAdapter. FragmentPagerAdapter představuje každou stránku jako Fragment stránku, která se trvale uchovává ve správci fragmentů, dokud se uživatel může vrátit na stránku. Když uživatel prochází stránkami , ViewPagerFragmentPagerAdapter extrahuje informace ze zdroje dat a používá ho k vytvoření FragmentzobrazeníViewPager.

Při implementaci FragmentPagerAdapter, musíte přepsat následující:

  • Count – vlastnost jen pro čtení, která vrací počet dostupných zobrazení (stránek).

  • GetItem – Vrátí fragment, který se má zobrazit pro zadanou stránku.

Přidejte nový soubor s názvem FlashCardDeckAdapter.cs a nahraďte jeho obsah následujícím kódem:

using System;
using Android.Views;
using Android.Widget;
using Android.Support.V4.App;

namespace FlashCardPager
{
    class FlashCardDeckAdapter : FragmentPagerAdapter
    {
        public FlashCardDeckAdapter (Android.Support.V4.App.FragmentManager fm, FlashCardDeck flashCards)
            : base(fm)
        {
        }

        public override int Count
        {
            get { throw new NotImplementedException(); }
        }

        public override Android.Support.V4.App.Fragment GetItem(int position)
        {
            throw new NotImplementedException();
        }
    }
}

Tento kód zakryvuje základní FragmentPagerAdapter implementaci. V následujících částech je každá z těchto metod nahrazena funkčním kódem. Účelem konstruktoru je předat správce fragmentů konstruktoru FlashCardDeckAdapterzákladní třídy.

Implementace konstruktoru adaptéru

Když aplikace vytvoří instanci FlashCardDeckAdapter, poskytuje odkaz na správce fragmentů a vytvoří instanci FlashCardDeck. Do horní části FlashCardDeckAdapter třídy v FlashCardDeckAdapter.cs přidejte následující člennou proměnnou:

public FlashCardDeck flashCardDeck;

Do konstruktoru FlashCardDeckAdapter přidejte následující řádek kódu:

this.flashCardDeck = flashCards;

Tento řádek kódu ukládá FlashCardDeck instanci, kterou FlashCardDeckAdapter bude používat.

Implementace počtu

Implementace Count je poměrně jednoduchá: vrátí počet flash karet v balíčku flash karet. Nahraďte Count následujícím kódem:

public override int Count
{
    get { return flashCardDeck.NumCards; }
}

Vlastnost NumCards FlashCardDeck vrátí počet flash karet (počet fragmentů) v sadě dat.

Implementace GetItem

Metoda GetItem vrátí fragment přidružený k dané pozici. Když GetItem je volána pozice v balíčku flash karet, vrátí nakonfigurované FlashCardFragment zobrazení problému s flash kartou na této pozici. Nahraďte metodu GetItem následujícím kódem:

public override Android.Support.V4.App.Fragment GetItem(int position)
{
    return (Android.Support.V4.App.Fragment)
        FlashCardFragment.newInstance (
            flashCardDeck[position].Problem, flashCardDeck[position].Answer);
}

Tento kód provádí následující úkony:

  1. Vyhledá řetězec matematického problému v FlashCardDeck balíčku pro zadanou pozici.

  2. Vyhledá řetězec odpovědí v FlashCardDeck balíčku pro zadanou pozici.

  3. Volá metodu FlashCardFragment newInstancetovárny , předávání problému s flash kartou a odpovědi řetězce.

  4. Vytvoří a vrátí novou flash kartu Fragment , která obsahuje text otázky a odpovědi pro danou pozici.

Když se ViewPager zobrazí na obrázku positionFragment , zobrazí TextBox obsahující řetězec matematického problému umístěný v position souboru flash karty.

Přidání adaptéru do ViewPageru

Teď, když FlashCardDeckAdapter je implementovaný, je čas ho přidat do souboru ViewPager. Do MainActivity.cs na konec OnCreate metody přidejte následující řádek kódu:

FlashCardDeckAdapter adapter =
    new FlashCardDeckAdapter(SupportFragmentManager, flashCards);
viewPager.Adapter = adapter;

Tento kód vytvoří FlashCardDeckAdapterinstanci , předávání v SupportFragmentManager prvním argumentu. SupportFragmentManager(Vlastnost FragmentActivity slouží k získání odkazu na objekt FragmentManager – další informace o správě FragmentManagerfragmentů.)

Základní implementace je teď hotová – sestavte a spusťte aplikaci. Na obrazovce by se měl zobrazit první obrázek balíčku flash karet, jak je znázorněno na levé straně na dalším snímku obrazovky. Potáhnutím prstem doleva zobrazíte další flash karty a potom potáhnutím prstem doprava přejdete zpět přes balíček flash karet:

Ukázkové snímky obrazovky aplikace FlashCardPager bez indikátorů pageru

Přidání indikátoru pageru

Tato minimální ViewPager implementace zobrazí každou flash kartu v balíčku, ale neposkytuje žádnou informaci o tom, kde je uživatel v balíčku. Dalším krokem je přidání souboru PagerTabStrip. Informuje PagerTabStrip uživatele o tom, jaké číslo problému se zobrazí, a poskytuje navigační kontext zobrazením nápovědy předchozích a dalších flash karet.

Otevřete Prostředky/layout/Main.axml a přidejte PagerTabStrip do rozložení:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

  <android.support.v4.view.PagerTabStrip
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:layout_gravity="top"
      android:paddingBottom="10dp"
      android:paddingTop="10dp"
      android:textColor="#fff" />

</android.support.v4.view.ViewPager>

Když sestavíte a spustíte aplikaci, měli byste vidět prázdné PagerTabStrip zobrazení v horní části každé flash karty:

Closeup of PagerTabStrip without text

Zobrazení názvu

Pokud chcete přidat název na každou kartu stránky, implementujte metodu GetPageTitleFormatted v adaptéru. ViewPager volá GetPageTitleFormatted (pokud je implementováno) k získání řetězce nadpisu, který popisuje stránku na zadané pozici. Do třídy v FlashCardDeckAdapter.cs přidejte následující metoduFlashCardDeckAdapter:

public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
    return new Java.Lang.String("Problem " + (position + 1));
}

Tento kód převede pozici v balíčku flash karet na číslo problému. Výsledný řetězec se převede na Javu String , která se vrátí do ViewPager. Při spuštění aplikace s touto novou metodou se na každé stránce zobrazí číslo problému v :PagerTabStrip

Snímky obrazovky FlashCardPageru s číslem problému zobrazeným nad každou stránkou

Číslo problému můžete zobrazit v balíčku flash karet zobrazeném v horní části každé flash karty.

Zpracování uživatelského vstupu

FlashCardPager představuje řadu fragmentových flash karet v ViewPagersystému , ale zatím nemá způsob, jak odhalit odpověď na každý problém. V této části se obslužná rutina události přidá do FlashCardFragment zobrazení odpovědi, když uživatel klepne na text problému s flash kartou.

Otevřete FlashCardFragment.cs a před vrácením zobrazení volajícímu na konec OnCreateView metody přidejte následující kód:

questionBox.Click += delegate
{
    Toast.MakeText(Activity.ApplicationContext,
            "Answer: " + answer, ToastLength.Short).Show();
};

Tato Click obslužná rutina události zobrazí odpověď v informačním příspěvku, který se zobrazí, když uživatel klepne na TextBoxpoložku . Proměnná answer byla inicializována dříve, když byly informace o stavu načteny ze sady, která byla předána OnCreateView. Sestavte a spusťte aplikaci a potom klepnutím na text problému na každé flash kartě zobrazte odpověď:

Snímky obrazovky s informačními zprávami aplikace FlashCardPager při klepnutí na matematický problém

FlashCardPager uvedený v tomto návodu používá odvozený MainActivity z FragmentActivity, ale můžete také odvodit MainActivity AppCompatActivity (který také poskytuje podporu pro správu fragmentů).

Shrnutí

V tomto názorném postupu najdete podrobný příklad vytvoření základní ViewPageraplikace pomocí s Fragment. Představil ukázkový zdroj dat obsahující otázky a odpovědi na flash karty, ViewPager rozložení pro zobrazení flash karet a FragmentPagerAdapter podtřídu ViewPager , která propojuje zdroj dat. Aby uživatel přecházel na flash karty, byly zahrnuty pokyny, které vysvětlují, jak přidat PagerTabStrip číslo problému v horní části každé stránky. Nakonec se přidal kód pro zpracování událostí, aby se zobrazila odpověď, když uživatel klepne na problém s flash kartou.