Freigeben über


ViewPager mit Fragmenten

ViewPager ist ein Layout-Manager, mit dem Sie gesturale Navigation implementieren können. Gesturale Navigation ermöglicht es dem Benutzer, nach links und rechts zu wischen, um Seiten mit Daten zu durchlaufen. In diesem Leitfaden wird erläutert, wie Sie eine wischbare Benutzeroberfläche mit ViewPager implementieren, wobei Fragmente als Datenseiten verwendet werden.

Übersicht

ViewPager wird häufig in Verbindung mit Fragmenten verwendet, sodass es einfacher ist, den Lebenszyklus jeder Seite in der ViewPager. In dieser exemplarischen Vorgehensweise wird verwendet, um eine App namens FlashCardPager zu erstellen, ViewPager die eine Reihe von mathematischen Problemen bei Flash-Karte s darstellt. Jedes Flash-Karte wird als Fragment implementiert. Der Benutzer wischen nach links und rechts durch den Blitz Karte und tippt auf ein mathematisches Problem, um seine Antwort anzuzeigen. Diese App erstellt eine Fragment Instanz für jeden Flash-Karte und implementiert einen Adapter, der von FragmentPagerAdapter. In Viewpager und Views wurde der Großteil der Arbeit in MainActivity Lebenszyklusmethoden durchgeführt. In FlashCardPager werden die meisten Arbeiten von einer Fragment seiner Lebenszyklusmethoden durchgeführt.

In diesem Leitfaden werden die Grundlagen von Fragmenten nicht behandelt – wenn Sie noch nicht mit Fragmenten in Xamarin.Android vertraut sind, lesen Sie Fragmente , die Ihnen bei den ersten Schritten mit Fragmenten helfen.

Starten eines App-Projekts

Erstellen Sie ein neues Android-Projekt namens FlashCardPager. Starten Sie als Nächstes die NuGet-Paket-Manager (weitere Informationen zum Installieren von NuGet-Paketen finden Sie unter Walkthrough: Including a NuGet in your project). Suchen und installieren Sie das Xamarin.Android.Support.v4-Paket , wie in Viewpager und Views erläutert.

Hinzufügen einer Beispieldatenquelle

In FlashCardPager ist die Datenquelle eine Reihe von Flash-Karte, die durch die FlashCardDeck Klasse dargestellt werden. Diese Datenquelle stellt den Inhalt des ViewPager Elements zur Seite. FlashCardDeck enthält eine vorgefertigte Sammlung mathematischer Probleme und Antworten. Der FlashCardDeck Konstruktor erfordert keine Argumente:

FlashCardDeck flashCards = new FlashCardDeck();

Die Sammlung von Flash-Karte in FlashCardDeck ist so organisiert, dass jeder Flash-Karte von einem Indexer aufgerufen werden kann. Beispielsweise ruft die folgende Codezeile das vierte Flash-Karte Problem im Deck ab:

string problem = flashCardDeck[3].Problem;

Diese Codezeile ruft die entsprechende Antwort auf das vorherige Problem ab:

string answer = flashCardDeck[3].Answer;

Da die Implementierungsdetails FlashCardDeck für das Verständnis ViewPagernicht relevant sind, wird der FlashCardDeck Code hier nicht aufgeführt. Der zu verwendende FlashCardDeck Quellcode ist unter FlashCardDeck.cs verfügbar. Laden Sie diese Quelldatei herunter (oder kopieren Sie den Code und fügen Sie ihn in eine neue FlashCardDeck.cs Datei ein), und fügen Sie sie ihrem Projekt hinzu.

Erstellen eines ViewPager-Layouts

Öffnen Sie Ressourcen/layout/Main.axml , und ersetzen Sie deren Inhalt durch den folgenden XML-Code:

<?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>

Dieser XML-Code definiert eine ViewPager , die den gesamten Bildschirm belegt. Beachten Sie, dass Sie den vollqualifizierten Namen "android.support.v4.view.ViewPager " verwenden müssen, da ViewPager es in einer Supportbibliothek verpackt ist. ViewPager ist nur über die Android-Supportbibliothek v4 verfügbar. Sie ist im Android SDK nicht verfügbar.

Einrichten von ViewPager

Bearbeiten Sie MainActivity.cs , und fügen Sie die folgenden using Anweisungen hinzu:

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

Ändern Sie die MainActivity Klassendeklaration so, dass sie von FragmentActivity:

public class MainActivity : FragmentActivity

MainActivity wird vonFragmentActivity (statt Activity) abgeleitet, da FragmentActivity die Unterstützung von Fragmenten verwaltet werden kann. Ersetzen Sie die OnCreate-Methode durch folgenden Code:

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

Dieser Code bewirkt Folgendes:

  1. Legt die Ansicht aus der Main.axml-Layoutressource fest.

  2. Ruft einen Verweis auf das ViewPager Layout ab.

  3. Instanziiert eine neue FlashCardDeck Als Datenquelle.

Wenn Sie diesen Code erstellen und ausführen, sollte eine Anzeige angezeigt werden, die dem folgenden Screenshot ähnelt:

Screenshot der FlashCardPager-App mit leerem ViewPager

An diesem Punkt ist die ViewPager leer, weil es an den Fragmenten fehlt, die verwendet werden, füllen die ViewPager, und es fehlt ein Adapter zum Erstellen dieser Fragmente aus den Daten in FlashCardDeck.

In den folgenden Abschnitten wird eine FlashCardFragment erstellt, um die Funktionalität der einzelnen Flash-Karte zu implementieren, und eine FragmentPagerAdapter wird erstellt, um die ViewPager aus Daten erstellten Fragmente in der FlashCardDeck.

Erstellen des Fragments

Jeder Flash-Karte wird von einem UI-Fragment verwaltet, das aufgerufen FlashCardFragmentwird. FlashCardFragmentIn der Ansicht werden die Informationen angezeigt, die mit einem einzigen Blitz Karte enthalten sind. Jede Instanz von FlashCardFragment wird von der ViewPager. FlashCardFragmentDie Ansicht besteht aus einer TextView Ansicht, die den Blitz Karte Problemtext anzeigt. Diese Ansicht implementiert einen Ereignishandler, der die Toast Antwort anzeigt, wenn der Benutzer auf den Flash Karte Frage tippt.

Erstellen des FlashCardFragment-Layouts

Bevor FlashCardFragment sie implementiert werden kann, muss das Layout definiert werden. Dieses Layout ist ein Fragmentcontainerlayout für ein einzelnes Fragment. Fügen Sie ein neues Android-Layout zu Ressourcen/Layout namens Flash Karte_layout.axml hinzu. Öffnen Sie Ressourcen/Layout/Flash Karte_layout.axml, und ersetzen Sie deren Inhalt durch den folgenden Code:

<?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>

Dieses Layout definiert ein einzelnes Flash-Karte Fragment. Jedes Fragment besteht aus einem TextView Fragment, das ein mathematisches Problem mit einer großen Schriftart (100sp) anzeigt. Dieser Text wird vertikal und horizontal auf dem Blitz Karte zentriert.

Erstellen der anfänglichen FlashCardFragment-Klasse

Fügen Sie eine neue Datei namens FlashCardFragment.cs hinzu, und ersetzen Sie deren Inhalt durch den folgenden Code:

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;
        }
    }
}

Mit diesem Code wird die wesentliche Fragment Definition herausgeblendet, die zum Anzeigen eines Flash-Karte verwendet wird. Beachten Sie, dass FlashCardFragment von der Unterstützungsbibliotheksversion abgeleitet wird, die Fragment in Android.Support.V4.App.Fragmentdefiniert ist. Der Konstruktor ist leer, sodass die newInstance Factorymethode zum Erstellen eines neuen FlashCardFragment anstelle eines Konstruktors verwendet wird.

Die OnCreateView Lifecycle-Methode erstellt und konfiguriert die TextView. Das Layout für die Fragmente TextView wird aufgeblasen und an den Aufrufer aufgeblasen TextView . LayoutInflater und ViewGroup werden übergeben OnCreateView , damit das Layout aufgeblasen werden kann. Das savedInstanceState Bündel enthält Daten, die OnCreateView zum Neustellen des Gespeicherten TextView Zustands verwendet werden.

Die Ansicht des Fragments wird durch den Aufruf inflater.Inflatevon . Das container Argument ist das übergeordnete Element der Ansicht, und das Flag weist den false Aufblaser an, nicht die aufgeblasene Ansicht zum übergeordneten Element der Ansicht hinzuzufügen (sie wird hinzugefügt, wenn ViewPager die Methode des Adapters GetItem später in dieser exemplarischen Vorgehensweise aufgerufen wird).

Hinzufügen von Statuscode zu FlashCardFragment

Wie eine Aktivität verfügt ein Fragment über ein Bundle Fragment, das zum Speichern und Abrufen des Zustands verwendet wird. In FlashCardPager wird dies Bundle verwendet, um die Frage und den Antworttext für den zugeordneten Flash-Karte zu speichern. Fügen Sie in FlashCardFragment.cs die folgenden Bundle Schlüssel am Anfang der FlashCardFragment Klassendefinition hinzu:

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

Ändern Sie die newInstance Factorymethode so, dass sie ein Bundle Objekt erstellt und die oben genannten Schlüssel verwendet, um den übergebenen Frage- und Antworttext im Fragment zu speichern, nachdem es instanziiert wurde:

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;
}

Ändern Sie die Fragment-Lebenszyklusmethode OnCreateView , um diese Informationen aus dem übergebenen Bundle abzurufen, und laden Sie den Fragetext in den 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;
}

Die answer Variable wird hier nicht verwendet, wird aber später verwendet, wenn dieser Datei Ereignishandlercode hinzugefügt wird.

Erstellen des Adapters

ViewPager verwendet ein Adaptercontrollerobjekt, das sich zwischen der ViewPager Datenquelle und der Datenquelle befindet (siehe Abbildung im ViewPager Adapter-Artikel ). Für den Zugriff auf diese Daten müssen Sie einen benutzerdefinierten Adapter bereitstellen, ViewPager der von PagerAdapter. Da in diesem Beispiel Fragmente verwendet werden, wird ein FragmentPagerAdapterFragmentPagerAdapter abgeleitet von PagerAdapter. FragmentPagerAdapter stellt jede Seite als Fragment eine Seite dar, die dauerhaft im Fragment-Manager aufbewahrt wird, solange der Benutzer zur Seite zurückkehren kann. Während der Benutzer durch Seiten des ViewPagerBereichs streift, werden die FragmentPagerAdapter Informationen aus der Datenquelle extrahiert und zum Erstellen Fragmentvon Informationen für die ViewPager Anzeige verwendet.

Wenn Sie eine FragmentPagerAdapterImplementierung implementieren, müssen Sie Folgendes außer Kraft setzen:

  • Count – Schreibgeschützte Eigenschaft, die die Anzahl der verfügbaren Ansichten (Seiten) zurückgibt.

  • GetItem – Gibt das Fragment zurück, das für die angegebene Seite angezeigt werden soll.

Fügen Sie eine neue Datei namens FlashCardDeckAdapter.cs hinzu, und ersetzen Sie deren Inhalt durch den folgenden Code:

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();
        }
    }
}

Dieser Code stubs die grundlegende Implementierung heraus FragmentPagerAdapter . In den folgenden Abschnitten wird jede dieser Methoden durch funktionierenden Code ersetzt. Der Zweck des Konstruktors besteht darin, den Fragment-Manager an den FlashCardDeckAdapterBasisklassenkonstruktor zu übergeben.

Implementieren des Adapterkonstruktors

Wenn die App instanziiert FlashCardDeckAdapter, stellt sie einen Verweis auf den Fragment-Manager und eine instanziierte Instanziierung bereit FlashCardDeck. Fügen Sie die folgende Membervariable am Anfang der FlashCardDeckAdapter Klasse in FlashCardDeckAdapter.cs hinzu:

public FlashCardDeck flashCardDeck;

Fügen Sie dem FlashCardDeckAdapter Konstruktor die folgende Codezeile hinzu:

this.flashCardDeck = flashCards;

In dieser Codezeile wird die FlashCardDeck Instanz gespeichert, die von der FlashCardDeckAdapter Anwendung verwendet wird.

Anzahl implementieren

Die Count Implementierung ist relativ einfach: Sie gibt die Anzahl der Flash-Karte im Flash Karte Deck zurück. Ersetzen Sie den Code Count durch folgenden Code:

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

Die NumCards Eigenschaft der FlashCardDeck Gibt die Anzahl der Flash-Karte s (Anzahl der Fragmente) im Dataset zurück.

Implementieren von GetItem

Die GetItem Methode gibt das Fragment zurück, das der angegebenen Position zugeordnet ist. Wenn GetItem eine Position im Flash-Karte Deck aufgerufen wird, wird ein FlashCardFragment konfigurierter Wert zurückgegeben, um den Blitz Karte Problem an dieser Position anzuzeigen. Ersetzen Sie die GetItem-Methode durch folgenden Code:

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

Dieser Code bewirkt Folgendes:

  1. Sucht nach der mathematischen Problemzeichenfolge im FlashCardDeck Deck für die angegebene Position.

  2. Sucht die Antwortzeichenfolge im FlashCardDeck Foliensatz nach der angegebenen Position.

  3. Ruft die FlashCardFragment Factorymethode newInstanceauf, wobei die Flash-Karte Problem- und Antwortzeichenfolgen übergeben werden.

  4. Erstellt und gibt einen neuen Flash-Karte zurück, Fragment der den Frage- und Antworttext für diese Position enthält.

Wenn das ViewPager At positiongerendert Fragment wird, wird die TextBox enthaltende mathematische Problemzeichenfolge angezeigt, die sich im Flash-Karte Deck befindetposition.

Hinzufügen des Adapters zum ViewPager

Nachdem die Implementierung erfolgt, ist es an der FlashCardDeckAdapter Zeit, sie dem ViewPager. Fügen Sie in MainActivity.cs die folgende Codezeile am Ende der OnCreate Methode hinzu:

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

Dieser Code instanziiert den FlashCardDeckAdapter, der das SupportFragmentManager erste Argument übergibt. (Die SupportFragmentManager Eigenschaft von FragmentActivity wird verwendet, um einen Verweis auf die FragmentManager – weitere Informationen zu den FragmentManagerFragmenten zu erhalten.)

Die Kernimplementierung ist jetzt abgeschlossen – Erstellen und Ausführen der App. Sie sollten das erste Bild des Blitzes sehen, Karte Foliensatz auf dem Bildschirm angezeigt wird, wie im nächsten Screenshot auf der linken Seite dargestellt. Wischen Sie nach links, um weitere Blitz-Karte anzuzeigen, und wischen Sie dann nach rechts, um durch den Blitz Karte Deck zurückzukehren:

Beispielfotos der FlashCardPager-App ohne Pagerindikatoren

Hinzufügen eines Pager-Indikators

Diese minimale ViewPager Implementierung zeigt jeden Flash-Karte im Deck an, bietet jedoch keine Hinweise darauf, wo sich der Benutzer innerhalb des Decks befindet. Der nächste Schritt besteht darin, ein PagerTabStrip. Der PagerTabStrip Benutzer informiert den Benutzer darüber, welche Problemnummer angezeigt wird, und stellt den Navigationskontext bereit, indem ein Hinweis auf die vorherigen und nächsten Flash-Karte angezeigt wird.

Öffnen Sie Ressourcen/Layout/Main.axml, und fügen Sie dem Layout ein:PagerTabStrip

<?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>

Wenn Sie die App erstellen und ausführen, sollte oben in jedem Flash-Karte die leere PagerTabStrip angezeigt werden:

Schließen von PagerTabStrip ohne Text

Anzeigen eines Titels

Um jedem Seitenregister einen Titel hinzuzufügen, implementieren Sie die GetPageTitleFormatted Methode im Adapter. ViewPager ruft GetPageTitleFormatted (falls implementiert) die Titelzeichenfolge auf, die die Seite an der angegebenen Position beschreibt. Fügen Sie der FlashCardDeckAdapter Klasse in FlashCardDeckAdapter.cs die folgende Methode hinzu:

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

Mit diesem Code wird die Position im Flash-Karte Deck in eine Problemnummer konvertiert. Die resultierende Zeichenfolge wird in einen Java-Code String konvertiert, der an die ViewPagerDatei zurückgegeben wird. Wenn Sie die App mit dieser neuen Methode ausführen, zeigt jede Seite die Problemnummer in der PagerTabStrip:

Screenshots von FlashCardPager mit der Problemnummer, die über jeder Seite angezeigt wird

Sie können hin und her wischen, um die Problemnummer im Flash-Karte Deck anzuzeigen, die oben in jedem Blitz Karte angezeigt wird.

Behandeln von Benutzereingaben

FlashCardPager stellt eine Reihe fragmentbasierter Flash-Karte in einer ViewPager, aber es hat noch keine Möglichkeit, die Antwort für jedes Problem zu zeigen. In diesem Abschnitt wird der FlashCardFragment Antwort ein Ereignishandler hinzugefügt, um die Antwort anzuzeigen, wenn der Benutzer auf den Flash Karte Problemtext tippt.

Öffnen Sie FlashCardFragment.cs , und fügen Sie am Ende der OnCreateView Methode den folgenden Code hinzu, bevor die Ansicht an den Aufrufer zurückgegeben wird:

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

Dieser Click Ereignishandler zeigt die Antwort in einem Popup an, das angezeigt wird, wenn der Benutzer auf die TextBoxSchaltfläche tippt. Die answer Variable wurde früher initialisiert, als Statusinformationen aus dem Bundle gelesen wurden, an OnCreateViewdas übergeben wurde. Erstellen Sie die App, und führen Sie sie aus, und tippen Sie dann auf den Problemtext auf jedem Flash-Karte, um die Antwort anzuzeigen:

Screenshots der FlashCardPager-App

Der in dieser exemplarischen Vorgehensweise dargestellte FlashCardPager verwendet einen MainActivity abgeleiteten FragmentActivityCode, kann aber auch MainActivity abgeleitet werden AppCompatActivity (was auch Unterstützung für die Verwaltung von Fragmenten bietet).

Zusammenfassung

Diese exemplarische Vorgehensweise enthält ein schrittweises Beispiel zum Erstellen einer einfachen ViewPagerbasierten App mit Fragments. Es wurde eine Beispieldatenquelle vorgestellt, die Flash-Karte Fragen und Antworten enthält, ein ViewPager Layout zum Anzeigen des Flash-Karte s und eine FragmentPagerAdapter Unterklasse, die die ViewPager Datenquelle verbindet. Um dem Benutzer zu helfen, durch die Flash-Karte zu navigieren, wurden Anweisungen hinzugefügt, in denen erläutert wird, wie die PagerTabStrip Problemnummer oben auf jeder Seite angezeigt wird. Schließlich wurde Code zur Ereignisbehandlung hinzugefügt, um die Antwort anzuzeigen, wenn der Benutzer auf ein Flash-Karte Problem tippt.