Share via


ViewPager con frammenti

ViewPager è un gestore di layout che consente di implementare lo spostamento gestuale. Lo spostamento gestuale consente all'utente di scorrere rapidamente verso sinistra e destra per scorrere le pagine di dati. Questa guida illustra come implementare un'interfaccia utente con scorrimento rapido con ViewPager, usando Frammenti come pagine di dati.

Panoramica

ViewPager viene spesso usato in combinazione con frammenti in modo da semplificare la gestione del ciclo di vita di ogni pagina in ViewPager. In questa procedura dettagliata ViewPager viene usata per creare un'app denominata FlashCardPager che presenta una serie di problemi matematici sulle schede flash. Ogni scheda flash viene implementata come frammento. L'utente scorre verso sinistra e verso destra attraverso le schede flash e tocca un problema matematico per rivelare la sua risposta. Questa app crea un'istanza Fragment per ogni scheda flash e implementa un adattatore derivato da FragmentPagerAdapter. In Viewpager e Views la maggior parte del lavoro è stata eseguita nei MainActivity metodi del ciclo di vita. In FlashCardPager, la maggior parte del lavoro verrà eseguita da un Fragment in uno dei metodi del ciclo di vita.

Questa guida non illustra le nozioni di base dei frammenti, se non si ha ancora familiarità con i frammenti in Xamarin.Android, vedere Frammenti per iniziare a usare i frammenti.

Avviare un progetto di app

Creare un nuovo progetto Android denominato FlashCardPager. Avviare quindi il Gestione pacchetti NuGet (per altre informazioni sull'installazione di pacchetti NuGet, vedere Procedura dettagliata: Inclusione di un nuGet nel progetto). Trovare e installare il pacchetto Xamarin.Android.Support.v4 come illustrato in Viewpager e Views.

Aggiungere un'origine dati di esempio

In FlashCardPager, l'origine dati è un mazzo di schede flash rappresentate dalla FlashCardDeck classe . Questa origine dati fornisce il con contenuto dell'elemento ViewPager . FlashCardDeck contiene una raccolta pronta di problemi matematici e risposte. Il FlashCardDeck costruttore non richiede argomenti:

FlashCardDeck flashCards = new FlashCardDeck();

La raccolta di schede flash in è organizzata in FlashCardDeck modo che ogni scheda flash sia accessibile da un indicizzatore. Ad esempio, la riga di codice seguente recupera il quarto problema della scheda flash nel mazzo:

string problem = flashCardDeck[3].Problem;

Questa riga di codice recupera la risposta corrispondente al problema precedente:

string answer = flashCardDeck[3].Answer;

Poiché i dettagli di implementazione di FlashCardDeck non sono rilevanti per comprendere ViewPager, il FlashCardDeck codice non è elencato qui. Il codice sorgente di FlashCardDeck è disponibile in FlashCardDeck.cs. Scaricare questo file di origine (o copiare e incollare il codice in un nuovo file di FlashCardDeck.cs ) e aggiungerlo al progetto.

Creare un layout ViewPager

Aprire Resources/layout/Main.axml e sostituirlo con il codice XML seguente:

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

Questo codice XML definisce un oggetto ViewPager che occupa l'intero schermo. Si noti che è necessario usare il nome completo android.support.v4.view.ViewPager perché ViewPager è incluso in un pacchetto in una libreria di supporto. ViewPager è disponibile solo dalla libreria di supporto Android v4. Non è disponibile in Android SDK.

Configurare ViewPager

Modificare MainActivity.cs e aggiungere le istruzioni seguenti using :

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

Modificare la dichiarazione di MainActivity classe in modo che venga derivata da FragmentActivity:

public class MainActivity : FragmentActivity

MainActivity è derivato daFragmentActivity (anziché Activity) perché FragmentActivity sa come gestire il supporto dei frammenti. Sostituire il metodo OnCreate con il codice seguente:

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

Il codice effettua quanto segue:

  1. Imposta la vista dalla risorsa di layout Main.axml .

  2. Recupera un riferimento all'oggetto ViewPager dal layout.

  3. Crea un'istanza di un nuovo FlashCardDeck oggetto come origine dati.

Quando si compila ed esegue questo codice, viene visualizzata una visualizzazione simile allo screenshot seguente:

Screenshot dell'app FlashCardPager con ViewPager vuoto

A questo punto, è ViewPager vuoto perché manca i frammenti usati popolano e ViewPagermanca un adattatore per la creazione di questi frammenti dai dati in FlashCardDeck.

Nelle sezioni seguenti viene creato un oggetto FlashCardFragment per implementare la funzionalità di ogni scheda flash e viene creato un FragmentPagerAdapter oggetto per connettere ViewPager i frammenti creati dai dati in FlashCardDeck.

Creare il frammento

Ogni scheda flash verrà gestita da un frammento dell'interfaccia utente denominato FlashCardFragment. FlashCardFragmentLa visualizzazione visualizzerà le informazioni contenute con una singola scheda flash. Ogni istanza di FlashCardFragment sarà ospitata da ViewPager. FlashCardFragmentLa visualizzazione sarà costituita da un oggetto TextView che visualizza il testo del problema della scheda flash. Questa visualizzazione implementerà un gestore eventi che usa un Toast oggetto per visualizzare la risposta quando l'utente tocca la domanda della scheda flash.

Creare il layout FlashCardFragment

Prima di FlashCardFragment poter essere implementato, è necessario definirne il layout. Questo layout è un layout del contenitore di frammenti per un singolo frammento. Aggiungere un nuovo layout Android a Resources/layout denominato flashcard_layout.axml. Aprire Resources/layout/flashcard_layout.axml e sostituirlo con il codice seguente:

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

Questo layout definisce un singolo frammento di scheda flash; ogni frammento è costituito da un oggetto TextView che visualizza un problema matematico usando un tipo di carattere grande (100sp). Questo testo è centrato verticalmente e orizzontalmente sulla scheda flash.

Creare la classe FlashCardFragment iniziale

Aggiungere un nuovo file denominato FlashCardFragment.cs e sostituirlo con il codice seguente:

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

Questo codice stuba la definizione essenziale Fragment che verrà usata per visualizzare una scheda flash. Si noti che FlashCardFragment è derivato dalla versione della libreria di supporto di Fragment definita in Android.Support.V4.App.Fragment. Il costruttore è vuoto in modo che il newInstance metodo factory venga usato per creare un nuovo FlashCardFragment anziché un costruttore.

Il OnCreateView metodo del ciclo di vita crea e configura .TextView Gonfia il layout per il frammento e restituisce l'oggetto TextView gonfiato TextView al chiamante. LayoutInflater e ViewGroup vengono passati a OnCreateView in modo che possa gonfiare il layout. Il savedInstanceState bundle contiene dati che OnCreateView usano per ricreare l'oggetto TextView da uno stato salvato.

La visualizzazione del frammento viene gonfiata in modo esplicito dalla chiamata a inflater.Inflate. L'argomento container è l'elemento padre della visualizzazione e il false flag indica all'gonfiatore di evitare di aggiungere la visualizzazione gonfiata all'elemento padre della visualizzazione (verrà aggiunto quando ViewPager il metodo dell'adattatore GetItem verrà aggiunto più avanti in questa procedura dettagliata).

Aggiungere codice di stato a FlashCardFragment

Analogamente a un'attività, un frammento ha un Bundle oggetto che usa per salvare e recuperare il relativo stato. In FlashCardPager questo Bundle viene usato per salvare il testo della domanda e della risposta per la scheda flash associata. In FlashCardFragment.cs aggiungere le chiavi seguenti Bundle all'inizio della definizione della FlashCardFragment classe:

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

Modificare il newInstance metodo factory in modo che crei un Bundle oggetto e usi le chiavi precedenti per archiviare il testo della domanda e della risposta passato nel frammento dopo che è stata creata un'istanza:

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

Modificare il metodo OnCreateView del ciclo di vita del frammento per recuperare queste informazioni dal bundle passato e caricare il testo della TextBoxdomanda in :

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

La answer variabile non viene usata qui, ma verrà usata in un secondo momento quando il codice del gestore eventi viene aggiunto a questo file.

Creare l'adapter

ViewPagerusa un oggetto controller adattatore che si trova tra l'oggetto ViewPager e l'origine dati (vedere la figura nell'articolo Adapter ViewPager). Per accedere a questi dati, ViewPager è necessario fornire un adattatore personalizzato derivato da PagerAdapter. Poiché in questo esempio vengono usati frammenti, viene usato un FragmentPagerAdapter oggetto , FragmentPagerAdapter derivato da PagerAdapter. FragmentPagerAdapter rappresenta ogni pagina come oggetto Fragment che viene mantenuto in modo permanente nel gestore frammenti, purché l'utente possa tornare alla pagina. Quando l'utente scorre rapidamente le pagine di ViewPager, FragmentPagerAdapter estrae le informazioni dall'origine dati e le usa per creare Fragmentper la ViewPager visualizzazione di .

Quando si implementa un FragmentPagerAdapter, è necessario eseguire l'override di quanto segue:

  • Count : proprietà di sola lettura che restituisce il numero di visualizzazioni (pagine) disponibili.

  • GetItem : restituisce il frammento da visualizzare per la pagina specificata.

Aggiungere un nuovo file denominato FlashCardDeckAdapter.cs e sostituirlo con il codice seguente:

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

Questo codice stuba l'implementazione essenziale FragmentPagerAdapter . Nelle sezioni seguenti ognuno di questi metodi viene sostituito con codice funzionante. Lo scopo del costruttore è passare il gestore frammenti al FlashCardDeckAdaptercostruttore della classe di base.

Implementare il costruttore dell'adapter

Quando l'app crea un'istanza di FlashCardDeckAdapter, fornisce un riferimento al gestore dei frammenti e un'istanza di FlashCardDeck. Aggiungere la variabile membro seguente all'inizio della FlashCardDeckAdapter classe in FlashCardDeckAdapter.cs:

public FlashCardDeck flashCardDeck;

Aggiungere la riga di codice seguente al FlashCardDeckAdapter costruttore:

this.flashCardDeck = flashCards;

Questa riga di codice archivia l'istanza FlashCardDeck che FlashCardDeckAdapter verrà usata da .

Implementa conteggio

L'implementazione Count è relativamente semplice: restituisce il numero di schede flash nel mazzo di schede flash. Sostituisci Count con il seguente codice:

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

La NumCards proprietà di FlashCardDeck restituisce il numero di schede flash (numero di frammenti) nel set di dati.

Implementare GetItem

Il GetItem metodo restituisce il frammento associato alla posizione specificata. Quando GetItem viene chiamato per una posizione nel mazzo di schede flash, restituisce un FlashCardFragment configurato per visualizzare il problema della scheda flash in tale posizione. Sostituire il metodo GetItem con il codice seguente:

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

Il codice effettua quanto segue:

  1. Cerca la stringa del problema matematico nel FlashCardDeck mazzo per la posizione specificata.

  2. Cerca la stringa di risposta nel FlashCardDeck mazzo per la posizione specificata.

  3. Chiama il FlashCardFragment metodo newInstancefactory , passando le stringhe di risposta e il problema della scheda flash.

  4. Crea e restituisce una nuova scheda Fragment flash contenente il testo della domanda e della risposta per tale posizione.

Quando esegue il rendering di FragmentViewPager in position, visualizza l'oggetto TextBox contenente la stringa di problema matematico che si trova position nel mazzo di schede flash.

Aggiungere l'adapter a ViewPager

Ora che FlashCardDeckAdapter è implementato, è il momento di aggiungerlo a ViewPager. In MainActivity.cs aggiungere la riga di codice seguente alla fine del OnCreate metodo :

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

Questo codice crea un'istanza di FlashCardDeckAdapter, passando nella SupportFragmentManager classe nel primo argomento. La SupportFragmentManager proprietà FragmentActivity viene usata per ottenere un riferimento a FragmentManager . Per altre informazioni su FragmentManager, vedere Gestione di frammenti.

L'implementazione principale è ora completa: compilare ed eseguire l'app. Verrà visualizzata la prima immagine del mazzo di carte flash sullo schermo, come illustrato a sinistra nello screenshot successivo. Scorri verso sinistra per visualizzare più schede flash, quindi scorri verso destra per tornare indietro attraverso il mazzo di schede flash:

Screenshot di esempio dell'app FlashCardPager senza indicatori di cercapersone

Aggiungere un indicatore di cercapersone

Questa implementazione minima ViewPager visualizza ogni scheda flash nel mazzo, ma non fornisce indicazioni sulla posizione dell'utente all'interno del mazzo. Il passaggio successivo consiste nell'aggiungere un oggetto PagerTabStrip. PagerTabStrip Informa l'utente su quale numero di problema viene visualizzato e fornisce il contesto di spostamento visualizzando un suggerimento delle schede flash precedenti e successive.

Aprire Resources/layout/Main.axml e aggiungere un oggetto PagerTabStrip al layout:

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

Quando si compila ed esegue l'app, viene visualizzato il vuoto PagerTabStrip visualizzato nella parte superiore di ogni scheda flash:

Chiusura di PagerTabStrip senza testo

Visualizzare un titolo

Per aggiungere un titolo a ogni scheda della pagina, implementare il GetPageTitleFormatted metodo nell'adattatore. ViewPager chiama GetPageTitleFormatted (se implementato) per ottenere la stringa del titolo che descrive la pagina nella posizione specificata. Aggiungere il metodo seguente alla FlashCardDeckAdapter classe in FlashCardDeckAdapter.cs:

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

Questo codice converte la posizione nel mazzo di carte flash in un numero di problema. La stringa risultante viene convertita in java String restituita a ViewPager. Quando si esegue l'app con questo nuovo metodo, ogni pagina visualizza il numero di problema in PagerTabStrip:

Screenshot di FlashCardPager con il numero di problema visualizzato sopra ogni pagina

È possibile scorrere rapidamente avanti e indietro per vedere il numero di problema nel mazzo di schede flash che viene visualizzato nella parte superiore di ogni scheda flash.

Gestire l'input utente

FlashCardPager presenta una serie di schede flash basate su frammenti in un ViewPager, ma non ha ancora un modo per rivelare la risposta per ogni problema. In questa sezione viene aggiunto un gestore eventi a FlashCardFragment per visualizzare la risposta quando l'utente tocca il testo del problema della scheda flash.

Aprire FlashCardFragment.cs e aggiungere il codice seguente alla fine del OnCreateView metodo subito prima che la vista venga restituita al chiamante:

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

Questo Click gestore eventi visualizza la risposta in un avviso popup visualizzato quando l'utente tocca .TextBox La answer variabile è stata inizializzata in precedenza quando le informazioni sullo stato sono state lette dal bundle passato a OnCreateView. Compilare ed eseguire l'app, quindi toccare il testo del problema in ogni scheda flash per visualizzare la risposta:

Screenshot degli avvisi popup dell'app FlashCardPager quando viene toccato il problema matematico

FlashCardPager presentato in questa procedura dettagliata usa un MainActivity derivato da FragmentActivity, ma è anche possibile derivare MainActivity da AppCompatActivity (che fornisce anche il supporto per la gestione dei frammenti).

Riepilogo

Questa procedura dettagliata ha fornito un esempio dettagliato di come creare un'app di base ViewPagerbasata su s Fragment. Ha presentato un'origine dati di esempio contenente domande e risposte sulle schede flash, un ViewPager layout per visualizzare le schede flash e una FragmentPagerAdapter sottoclasse che connette l'oggetto ViewPager all'origine dati. Per aiutare l'utente a spostarsi tra le schede flash, sono state incluse istruzioni che spiegano come aggiungere un PagerTabStrip per visualizzare il numero di problema nella parte superiore di ogni pagina. Infine, il codice di gestione degli eventi è stato aggiunto per visualizzare la risposta quando l'utente tocca un problema di scheda flash.