Obiekt ViewPager z fragmentami
ViewPager to menedżer układów, który umożliwia implementowanie nawigacji gesturalnej. Nawigacja gestyuralna umożliwia użytkownikowi przesunięcie w lewo i w prawo, aby przejść przez strony danych. W tym przewodniku wyjaśniono, jak zaimplementować interfejs użytkownika z możliwością przesunięcia za pomocą programu ViewPager przy użyciu fragmentów jako stron danych.
Omówienie
ViewPager
jest często używany w połączeniu z fragmentami, dzięki czemu łatwiej jest zarządzać cyklem życia każdej strony w obiekcie ViewPager
. W tym przewodniku ViewPager
jest używany do tworzenia aplikacji o nazwie FlashCardPager , która przedstawia serię problemów matematycznych na kartach flash. Każda karta flash jest implementowana jako fragment. Użytkownik przesuwa palcem w lewo i w prawo przez karty flash i dotyka problemu matematycznego, aby ujawnić swoją odpowiedź. Ta aplikacja tworzy Fragment
wystąpienie dla każdej karty flash i implementuje adapter pochodzący z FragmentPagerAdapter
klasy . W widoku i widokach większość pracy wykonano w MainActivity
metodach cyklu życia. W programie FlashCardPager większość pracy będzie wykonywana przez Fragment
jedną z metod cyklu życia.
Ten przewodnik nie obejmuje podstaw fragmentów — jeśli nie znasz jeszcze fragmentów na platformie Xamarin.Android, zobacz Fragmenty ułatwiające rozpoczęcie pracy z fragmentami.
Uruchamianie projektu aplikacji
Utwórz nowy projekt systemu Android o nazwie FlashCardPager. Następnie uruchom Menedżer pakietów NuGet (aby uzyskać więcej informacji na temat instalowania pakietów NuGet, zobacz Przewodnik: dołączanie pakietu NuGet w projekcie). Znajdź i zainstaluj pakiet Xamarin.Android.Support.v4 zgodnie z opisem w temacie Viewpager and Views(Widoki).
Dodawanie przykładowego źródła danych
W programie FlashCardPager źródło danych jest talii kart flash reprezentowanych przez klasę FlashCardDeck
; to źródło danych dostarcza ViewPager
zawartość elementu. FlashCardDeck
zawiera gotową kolekcję problemów matematycznych i odpowiedzi. Konstruktor FlashCardDeck
nie wymaga żadnych argumentów:
FlashCardDeck flashCards = new FlashCardDeck();
Kolekcja kart flash w programie FlashCardDeck
jest zorganizowana tak, aby dostęp do każdej karty flash był dostępny przez indeksator. Na przykład następujący wiersz kodu pobiera czwarty problem z kartą flash na pokładzie:
string problem = flashCardDeck[3].Problem;
Ten wiersz kodu pobiera odpowiadającą odpowiedź na poprzedni problem:
string answer = flashCardDeck[3].Answer;
Ponieważ szczegóły FlashCardDeck
implementacji nie są istotne dla zrozumienia ViewPager
, FlashCardDeck
kod nie jest wymieniony tutaj.
Kod źródłowy, który FlashCardDeck
ma być dostępny w FlashCardDeck.cs.
Pobierz ten plik źródłowy (lub skopiuj i wklej kod do nowego pliku FlashCardDeck.cs ) i dodaj go do projektu.
Tworzenie układu viewPager
Otwórz plik Resources/layout/Main.axml i zastąp jego zawartość następującym kodem 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>
Ten kod XML definiuje element ViewPager
, który zajmuje cały ekran. Należy pamiętać, że należy użyć w pełni kwalifikowanej nazwy android.support.v4.view.ViewPager , ponieważ ViewPager
jest spakowana w bibliotece pomocy technicznej. ViewPager
Jest dostępny tylko z biblioteki pomocy technicznej systemu Android w wersji 4; nie jest dostępny w zestawie ANDROID SDK.
Konfigurowanie programu ViewPager
Edytuj MainActivity.cs i dodaj następujące using
instrukcje:
using Android.Support.V4.View;
using Android.Support.V4.App;
Zmień deklarację MainActivity
klasy, aby pochodziła z FragmentActivity
klasy :
public class MainActivity : FragmentActivity
MainActivity
pochodzi zFragmentActivity
elementu (zamiast Activity
), ponieważ FragmentActivity
wie, jak zarządzać obsługą fragmentów. Zastąp metodę OnCreate
poniższym kodem:
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
ViewPager viewPager = FindViewById<ViewPager>(Resource.Id.viewpager);
FlashCardDeck flashCards = new FlashCardDeck();
}
Ten kod powoduje wykonanie następujących czynności:
Ustawia widok z zasobu układu Main.axml .
Pobiera odwołanie do
ViewPager
elementu z układu.Tworzy wystąpienie nowego
FlashCardDeck
źródła danych.
Podczas tworzenia i uruchamiania tego kodu powinien zostać wyświetlony ekran podobny do poniższego zrzutu ekranu:
W tym momencie wartość jest pusta, ViewPager
ponieważ brakuje fragmentów, które są używane do wypełniania elementu , i brakuje karty do tworzenia tych fragmentów z danych w narzędziu ViewPager
FlashCardDeck.
W poniższych sekcjach element jest FlashCardFragment
tworzony w celu zaimplementowania funkcji każdej karty flash, a element FragmentPagerAdapter
jest tworzony w celu nawiązania połączenia z ViewPager
fragmentami utworzonymi na podstawie danych w obiekcie FlashCardDeck
.
Tworzenie fragmentu
Każda karta flash będzie zarządzana przez fragment interfejsu użytkownika o nazwie FlashCardFragment
. FlashCardFragment
W widoku będą wyświetlane informacje zawarte w jednej karcie flash. Każde wystąpienie programu będzie hostowane FlashCardFragment
przez program ViewPager
.
FlashCardFragment
Widok będzie składać się z elementu TextView
, który wyświetla tekst problemu karty flash. Ten widok zaimplementuje procedurę obsługi zdarzeń, która używa elementu Toast
, aby wyświetlić odpowiedź, gdy użytkownik naciągnie pytanie karty flash.
Tworzenie układu FlashCardFragment
Przed FlashCardFragment
wdrożeniem należy zdefiniować jego układ. Ten układ jest układem kontenera fragmentu dla pojedynczego fragmentu. Dodaj nowy układ systemu Android do folderu Resources/layout o nazwie flashcard_layout.axml. Otwórz plik Resources/layout/flashcard_layout.axml i zastąp jego zawartość następującym kodem:
<?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>
Ten układ definiuje pojedynczy fragment karty flash; każdy fragment składa się z elementu TextView
, który wyświetla problem matematyczny przy użyciu dużej czcionki (100sp). Ten tekst jest wyśrodkowany w pionie i poziomo na karcie flash.
Tworzenie początkowej klasy FlashCardFragment
Dodaj nowy plik o nazwie FlashCardFragment.cs i zastąp jego zawartość następującym kodem:
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;
}
}
}
Ten kod wyróżnia podstawową Fragment
definicję, która będzie używana do wyświetlania karty flash. Należy pamiętać, że FlashCardFragment
pochodzi z wersji biblioteki pomocy technicznej zdefiniowanej Fragment
w pliku Android.Support.V4.App.Fragment
. Konstruktor jest pusty, aby newInstance
metoda fabryki była używana do utworzenia nowego FlashCardFragment
zamiast konstruktora.
Metoda OnCreateView
cyklu życia tworzy i konfiguruje element TextView
. Zawyża układ fragmentu TextView
i zwraca zawyżone TextView
do elementu wywołującego. LayoutInflater
i ViewGroup
są przekazywane do OnCreateView
, aby można było zawyżać układ. Pakiet savedInstanceState
zawiera dane używane OnCreateView
do ponownego utworzenia TextView
elementu z zapisanego stanu.
Widok fragmentu jest jawnie zawyżony przez wywołanie metody inflater.Inflate
. Argument container
jest elementem nadrzędnym widoku, a false
flaga nakazuje nadmuchiwaczowi, aby powstrzymał się od dodania zawyżonego widoku do elementu nadrzędnego widoku (zostanie on dodany, gdy ViewPager
wywołanie metody adaptera GetItem
zostanie dodane w dalszej części tego przewodnika).
Dodawanie kodu stanu do funkcji FlashCardFragment
Podobnie jak działanie, fragment zawiera Bundle
element , którego używa do zapisywania i pobierania stanu. W programie FlashCardPager służy to Bundle
do zapisywania tekstu pytania i odpowiedzi dla skojarzonej karty flash. W FlashCardFragment.cs dodaj następujące Bundle
klucze na początku FlashCardFragment
definicji klasy:
private static string FLASH_CARD_QUESTION = "card_question";
private static string FLASH_CARD_ANSWER = "card_answer";
Zmodyfikuj metodę fabryki newInstance
, tak aby tworzyła Bundle
obiekt i używa powyższych kluczy do przechowywania przekazanego pytania i tekstu odpowiedzi w fragmentacji po utworzeniu wystąpienia:
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;
}
Zmodyfikuj metodę OnCreateView
cyklu życia fragmentu, aby pobrać te informacje z przekazanego pakietu i załadować tekst pytania do elementu 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;
}
Zmienna answer
nie jest używana w tym miejscu, ale będzie używana później, gdy kod programu obsługi zdarzeń zostanie dodany do tego pliku.
Tworzenie adaptera
ViewPager
używa obiektu kontrolera karty, który znajduje się między ViewPager
źródłem danych i (zobacz ilustrację w artykule Adapter ViewPager).
Aby uzyskać dostęp do tych danych, ViewPager
wymagane jest podanie niestandardowej karty pochodzącej z PagerAdapter
programu . Ponieważ w tym przykładzie użyto fragmentów, użyto elementu FragmentPagerAdapter
— FragmentPagerAdapter
pochodzi z PagerAdapter
klasy .
FragmentPagerAdapter
reprezentuje każdą stronę jako Fragment
trwale przechowywaną w menedżerze fragmentów tak długo, jak użytkownik może wrócić do strony. Gdy użytkownik szybko przesuwa strony ViewPager
obiektu , FragmentPagerAdapter
wyodrębnia informacje ze źródła danych i używa ich do utworzenia Fragment
ViewPager
elementu do wyświetlenia.
Podczas implementowania elementu FragmentPagerAdapter
należy zastąpić następujące elementy:
Count — właściwość tylko do odczytu, która zwraca liczbę dostępnych widoków (stron).
GetItem — zwraca fragment do wyświetlenia dla określonej strony.
Dodaj nowy plik o nazwie FlashCardDeckAdapter.cs i zastąp jego zawartość następującym kodem:
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();
}
}
}
Ten kod wyróżnia podstawową FragmentPagerAdapter
implementację. W poniższych sekcjach każda z tych metod jest zastępowana kodem roboczym. Celem konstruktora jest przekazanie menedżera fragmentów do FlashCardDeckAdapter
konstruktora klasy bazowej .
Implementowanie konstruktora adaptera
Gdy aplikacja tworzy wystąpienie FlashCardDeckAdapter
obiektu , dostarcza odwołanie do menedżera fragmentów i wystąpienie FlashCardDeck
elementu .
Dodaj następującą zmienną składową na początku FlashCardDeckAdapter
klasy w FlashCardDeckAdapter.cs:
public FlashCardDeck flashCardDeck;
Dodaj następujący wiersz kodu do konstruktora FlashCardDeckAdapter
:
this.flashCardDeck = flashCards;
Ten wiersz kodu przechowuje FlashCardDeck
wystąpienie, którego będzie używać FlashCardDeckAdapter
.
Implementowanie liczby
Implementacja Count
jest stosunkowo prosta: zwraca liczbę kart flash w talii karty flash. Zastąp Count
ciąg następującym kodem:
public override int Count
{
get { return flashCardDeck.NumCards; }
}
Właściwość NumCards
zwraca FlashCardDeck
liczbę kart flash (liczba fragmentów) w zestawie danych.
Implementowanie polecenia GetItem
Metoda GetItem
zwraca fragment skojarzony z daną pozycją. Po GetItem
wywołaniu pozycji w talii karty flash zwraca skonfigurowany do wyświetlania problemu z kartą FlashCardFragment
flash w tej pozycji. Zastąp metodę GetItem
poniższym kodem:
public override Android.Support.V4.App.Fragment GetItem(int position)
{
return (Android.Support.V4.App.Fragment)
FlashCardFragment.newInstance (
flashCardDeck[position].Problem, flashCardDeck[position].Answer);
}
Ten kod powoduje wykonanie następujących czynności:
Wyszukuje ciąg problemu matematyczny w
FlashCardDeck
pokładzie dla określonej pozycji.Wyszukuje ciąg odpowiedzi w
FlashCardDeck
pokładzie dla określonej pozycji.Wywołuje metodę
newInstance
fabrykiFlashCardFragment
, przekazując problem z kartą flash i ciągi odpowiedzi.Tworzy i zwraca nową kartę
Fragment
flash zawierającą tekst pytania i odpowiedzi dla tej pozycji.
Gdy renderuje element ViewPager
at position
, wyświetla TextBox
on zawierający ciąg problemu matematyczny znajdujący się w position
Fragment
talii karty flash.
Dodawanie adaptera do programu ViewPager
Teraz, gdy FlashCardDeckAdapter
element jest zaimplementowany, nadszedł czas, aby dodać go do elementu ViewPager
. W MainActivity.cs dodaj następujący wiersz kodu na końcu OnCreate
metody:
FlashCardDeckAdapter adapter =
new FlashCardDeckAdapter(SupportFragmentManager, flashCards);
viewPager.Adapter = adapter;
Ten kod tworzy wystąpienie FlashCardDeckAdapter
metody , przekazując SupportFragmentManager
element w pierwszym argumencie. (Właściwość SupportFragmentManager
FragmentActivity służy do uzyskiwania odwołania do FragmentManager
obiektu — aby uzyskać więcej informacji o FragmentManager
obiekcie , zobacz Zarządzanie fragmentami).
Podstawowa implementacja została ukończona — skompiluj i uruchom aplikację. Na ekranie powinien zostać wyświetlony pierwszy obraz pokładu karty flash, jak pokazano po lewej stronie na następnym zrzucie ekranu. Przesuń palcem w lewo, aby zobaczyć więcej kart flash, a następnie przesuń palcem w prawo, aby wrócić przez pokład karty flash:
Dodawanie wskaźnika pagera
Ta minimalna ViewPager
implementacja wyświetla każdą kartę flash na pokładzie, ale nie wskazuje na to, gdzie użytkownik znajduje się w talii. Następnym krokiem jest dodanie elementu PagerTabStrip
. Narzędzie PagerTabStrip
informuje użytkownika o numerze problemu i udostępnia kontekst nawigacji, wyświetlając wskazówkę poprzednich i następnych kart flash.
Otwórz plik Resources/layout/Main.axml i dodaj element PagerTabStrip
do układu:
<?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>
Podczas kompilowania i uruchamiania aplikacji powinna zostać wyświetlona pusta PagerTabStrip
w górnej części każdej karty flash:
Wyświetlanie tytułu
Aby dodać tytuł do każdej karty strony, zaimplementuj GetPageTitleFormatted
metodę na karcie adaptera. ViewPager
wywołania GetPageTitleFormatted
(jeśli zaimplementowano) w celu uzyskania ciągu tytułu opisującego stronę w określonej pozycji. Dodaj następującą metodę do FlashCardDeckAdapter
klasy w FlashCardDeckAdapter.cs:
public override Java.Lang.ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String("Problem " + (position + 1));
}
Ten kod konwertuje położenie na talii karty flash na numer problemu. Wynikowy ciąg jest konwertowany na język Java String
, który jest zwracany do elementu ViewPager
. Po uruchomieniu aplikacji przy użyciu tej nowej metody każda strona wyświetla numer problemu w pliku PagerTabStrip
:
Możesz przesunąć palcem wstecz i z powrotem, aby zobaczyć numer problemu w talii karty flash, która jest wyświetlana u góry każdej karty flash.
Obsługa danych wejściowych użytkownika
FlashCardPager przedstawia serię kart flash opartych na fragmentach w ViewPager
obiekcie , ale nie ma jeszcze sposobu na ujawnienie odpowiedzi dla każdego problemu. W tej sekcji do elementu zostanie dodana FlashCardFragment
procedura obsługi zdarzeń, aby wyświetlić odpowiedź, gdy użytkownik naciągnie tekst problemu karty flash.
Otwórz FlashCardFragment.cs i dodaj następujący kod na końcu OnCreateView
metody tuż przed zwróceniem widoku do obiektu wywołującego:
questionBox.Click += delegate
{
Toast.MakeText(Activity.ApplicationContext,
"Answer: " + answer, ToastLength.Short).Show();
};
Ta Click
procedura obsługi zdarzeń wyświetla odpowiedź w wyskakujących wyskakujących komunikatach, gdy użytkownik naciągnie TextBox
element . Zmienna answer
została zainicjowana wcześniej, gdy informacje o stanie zostały odczytane z pakietu przekazanego do OnCreateView
elementu . Skompiluj i uruchom aplikację, a następnie naciśnij tekst problemu na każdej karcie flash, aby zobaczyć odpowiedź:
Program FlashCardPager przedstawiony w tym przewodniku używa elementu pochodzącego MainActivity
z FragmentActivity
elementu , ale można również pochodzić MainActivity
z AppCompatActivity
elementu (który zapewnia również obsługę zarządzania fragmentami).
Podsumowanie
W tym przewodniku przedstawiono szczegółowy przykład tworzenia podstawowej ViewPager
aplikacji Fragment
opartej na języku s. Przedstawiono przykładowe źródło danych zawierające pytania i odpowiedzi dotyczące karty flash, ViewPager
układ umożliwiający wyświetlenie kart flash oraz podklasę FragmentPagerAdapter
łączącą źródło ViewPager
danych. Aby ułatwić użytkownikowi nawigowanie po kartach flash, zawarto instrukcje objaśniające sposób dodawania elementu w PagerTabStrip
celu wyświetlenia numeru problemu w górnej części każdej strony. Na koniec dodano kod obsługi zdarzeń, aby wyświetlić odpowiedź, gdy użytkownik naciągnie problem z kartą flash.