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 ViewPager
nicht 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:
Legt die Ansicht aus der Main.axml-Layoutressource fest.
Ruft einen Verweis auf das
ViewPager
Layout ab.Instanziiert eine neue
FlashCardDeck
Als Datenquelle.
Wenn Sie diesen Code erstellen und ausführen, sollte eine Anzeige angezeigt werden, die dem folgenden Screenshot ähnelt:
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 FlashCardFragment
wird. FlashCardFragment
In der Ansicht werden die Informationen angezeigt, die mit einem einzigen Blitz Karte enthalten sind. Jede Instanz von FlashCardFragment
wird von der ViewPager
.
FlashCardFragment
Die 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.Fragment
definiert 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.Inflate
von . 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 FragmentPagerAdapter
– FragmentPagerAdapter
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 ViewPager
Bereichs streift, werden die FragmentPagerAdapter
Informationen aus der Datenquelle extrahiert und zum Erstellen Fragment
von Informationen für die ViewPager
Anzeige verwendet.
Wenn Sie eine FragmentPagerAdapter
Implementierung 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 FlashCardDeckAdapter
Basisklassenkonstruktor 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:
Sucht nach der mathematischen Problemzeichenfolge im
FlashCardDeck
Deck für die angegebene Position.Sucht die Antwortzeichenfolge im
FlashCardDeck
Foliensatz nach der angegebenen Position.Ruft die
FlashCardFragment
FactorymethodenewInstance
auf, wobei die Flash-Karte Problem- und Antwortzeichenfolgen übergeben werden.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 position
gerendert 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 FragmentManager
Fragmenten 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:
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:
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 ViewPager
Datei zurückgegeben wird. Wenn Sie die App mit dieser neuen Methode ausführen, zeigt jede Seite die Problemnummer in der PagerTabStrip
:
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 TextBox
Schaltfläche tippt. Die answer
Variable wurde früher initialisiert, als Statusinformationen aus dem Bundle gelesen wurden, an OnCreateView
das ü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:
Der in dieser exemplarischen Vorgehensweise dargestellte FlashCardPager verwendet einen MainActivity
abgeleiteten FragmentActivity
Code, 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 ViewPager
basierten App mit Fragment
s. 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.