Condividi tramite


Esempio di Basic RecyclerView

Per comprendere il funzionamento RecyclerView in un'applicazione tipica, questo argomento illustra un semplice esempio di codice che usa RecyclerView per visualizzare una raccolta di foto di grandi dimensioni:

Due screenshot di un'app RecyclerView che usa CardView per visualizzare le foto

RecyclerViewer usa CardView per implementare ogni elemento fotografico nel RecyclerView layout. A causa dei RecyclerViewvantaggi delle prestazioni, questa app di esempio è in grado di scorrere rapidamente un'ampia raccolta di foto senza problemi e senza ritardi evidenti.

Un'origine dati di esempio

In questa app di esempio, un'origine dati "album foto" (rappresentata dalla classe ) fornisce RecyclerView contenuto dell'elementoPhotoAlbum. PhotoAlbum è una raccolta di foto con didascalie; quando si crea un'istanza, si ottiene una collezione pronta per 32 foto:

PhotoAlbum mPhotoAlbum = new PhotoAlbum ();

Ogni istanza di foto in PhotoAlbum espone le proprietà che consentono di leggere il relativo ID risorsa immagine, PhotoIDe la relativa stringa di didascalia, Caption. La raccolta di foto è organizzata in modo che ogni foto sia accessibile da un indicizzatore. Ad esempio, le righe di codice seguenti accedono all'ID risorsa immagine e alla didascalia per la decima foto nella raccolta:

int imageId = mPhotoAlbum[9].ImageId;
string caption = mPhotoAlbum[9].Caption;

PhotoAlbum fornisce anche un RandomSwap metodo che è possibile chiamare per scambiare la prima foto nella raccolta con una foto scelta casualmente altrove nella raccolta:

mPhotoAlbum.RandomSwap ();

Poiché i dettagli di implementazione di PhotoAlbum non sono rilevanti per comprendere RecyclerView, il PhotoAlbum codice sorgente non viene presentato qui.

Layout e inizializzazione

Il file di layout Main.axml è costituito da un singolo RecyclerView all'interno di un LinearLayoutoggetto :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerView"
        android:scrollbars="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />
</LinearLayout>

Si noti che è necessario usare il nome completo android.support.v7.widget.RecyclerView perché RecyclerView è incluso in un pacchetto in una libreria di supporto. Il OnCreate metodo di MainActivity inizializza questo layout, crea un'istanza dell'adapter e prepara l'origine dati sottostante:

public class MainActivity : Activity
{
    RecyclerView mRecyclerView;
    RecyclerView.LayoutManager mLayoutManager;
    PhotoAlbumAdapter mAdapter;
    PhotoAlbum mPhotoAlbum;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);

        // Prepare the data source:
        mPhotoAlbum = new PhotoAlbum ();

        // Instantiate the adapter and pass in its data source:
        mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);

        // Set our view from the "main" layout resource:
        SetContentView (Resource.Layout.Main);

        // Get our RecyclerView layout:
        mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);

        // Plug the adapter into the RecyclerView:
        mRecyclerView.SetAdapter (mAdapter);

Il codice effettua quanto segue:

  1. Crea un'istanza dell'origine PhotoAlbum dati.

  2. Passa l'origine dati dell'album fotografico al costruttore dell'adattatore , PhotoAlbumAdapter definito più avanti in questa guida. Si noti che è considerata una procedura consigliata per passare l'origine dati come parametro al costruttore dell'adattatore.

  3. Ottiene l'oggetto RecyclerView dal layout.

  4. Collega l'adattatore all'istanza RecyclerView chiamando il RecyclerView SetAdapter metodo come illustrato in precedenza.

Gestione layout

Ogni elemento in RecyclerView è costituito da un CardView oggetto che contiene un'immagine e una didascalia foto (i dettagli sono trattati nella sezione View Holder sotto). Il valore predefinito LinearLayoutManager viene usato per disporre ognuno di essi CardView in una disposizione di scorrimento verticale:

mLayoutManager = new LinearLayoutManager (this);
mRecyclerView.SetLayoutManager (mLayoutManager);

Questo codice risiede nel metodo dell'attività OnCreate principale. Il costruttore per la gestione layout richiede un contesto, quindi viene MainActivity passato usando this come illustrato in precedenza.

Invece di usare il valore predefinito LinearLayoutManager, è possibile collegare un gestore layout personalizzato che visualizza due CardView elementi affiancati, implementando un effetto di animazione di rotazione pagina per attraversare la raccolta di foto. Più avanti in questa guida verrà illustrato un esempio di come modificare il layout scambiando in un gestore di layout diverso.

Visualizza supporto

La classe del titolare della vista è denominata PhotoViewHolder. Ogni PhotoViewHolder istanza contiene riferimenti a ImageView e TextView di un elemento di riga associato, disposto in un CardView diagramma riportato di seguito:

Diagramma di CardView contenente imageView e TextView

PhotoViewHolder deriva da RecyclerView.ViewHolder e contiene proprietà per archiviare i riferimenti a ImageView e TextView visualizzati nel layout precedente. PhotoViewHolder è costituito da due proprietà e da un costruttore:

public class PhotoViewHolder : RecyclerView.ViewHolder
{
    public ImageView Image { get; private set; }
    public TextView Caption { get; private set; }

    public PhotoViewHolder (View itemView) : base (itemView)
    {
        // Locate and cache view references:
        Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
        Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
    }
}

In questo esempio di codice, il PhotoViewHolder costruttore viene passato un riferimento alla visualizzazione elemento padre (l'oggetto ) che PhotoViewHolder esegue il CardViewwrapping. Si noti che la visualizzazione elemento padre viene sempre inoltrata al costruttore di base. Il PhotoViewHolder costruttore chiama FindViewById nella visualizzazione elemento padre per individuare rispettivamente i riferimenti ImageView alla visualizzazione figlio e TextView, archiviando i risultati nelle Image proprietà e Caption . L'adattatore recupera in seguito i riferimenti di visualizzazione da queste proprietà quando aggiorna le CardViewvisualizzazioni figlio con nuovi dati.

Per altre informazioni su , vedere le informazioni di riferimento sulla RecyclerView.ViewHolderclasse RecyclerView.ViewHolder.

Adapter

L'adattatore carica ogni RecyclerView riga con dati per una particolare fotografia. Per una determinata fotografia in corrispondenza della posizione della riga P, ad esempio, l'adattatore individua i dati associati nella posizione P all'interno dell'origine dati e copia questi dati nell'elemento di riga nella posizione P dell'insieme RecyclerView . L'adattatore utilizza il supporto di visualizzazione per cercare i riferimenti per ImageView e TextView in tale posizione in modo che non sia necessario chiamare FindViewById ripetutamente tali visualizzazioni mentre l'utente scorre la raccolta di fotografie e riutilizza le visualizzazioni.

In RecyclerViewer una classe adapter deriva da RecyclerView.Adapter per creare PhotoAlbumAdapter:

public class PhotoAlbumAdapter : RecyclerView.Adapter
{
    public PhotoAlbum mPhotoAlbum;

    public PhotoAlbumAdapter (PhotoAlbum photoAlbum)
    {
        mPhotoAlbum = photoAlbum;
    }
    ...
}

Il membro contiene l'origine dati (album fotografico) passata al costruttore. Il mPhotoAlbum costruttore copia l'album fotografico in questa variabile membro. Vengono implementati i metodi obbligatori RecyclerView.Adapter seguenti:

  • OnCreateViewHolder : crea un'istanza del file di layout dell'elemento e del supporto di visualizzazione.

  • OnBindViewHolder : carica i dati nella posizione specificata nelle visualizzazioni i cui riferimenti vengono archiviati nel supporto di visualizzazione specificato.

  • ItemCount : restituisce il numero di elementi nell'origine dati.

Gestione layout chiama questi metodi mentre posiziona gli elementi all'interno di RecyclerView. L'implementazione di questi metodi viene esaminata nelle sezioni seguenti.

OnCreateViewHolder

Gestione layout chiama OnCreateViewHolder quando è RecyclerView necessario un nuovo supporto di visualizzazione per rappresentare un elemento. OnCreateViewHolder gonfia la visualizzazione elemento dal file di layout della visualizzazione ed esegue il wrapping della visualizzazione in una nuova PhotoViewHolder istanza. Il PhotoViewHolder costruttore individua e archivia i riferimenti alle visualizzazioni figlio nel layout come descritto in precedenza in View Holder.

Ogni elemento di riga è rappresentato da un CardView oggetto che contiene ( ImageView per la foto) e un TextView (per la didascalia). Questo layout si trova nel file PhotoCardView.axml:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:card_view="http://schemas.android.com/apk/res-auto"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content">
    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        card_view:cardElevation="4dp"
        card_view:cardUseCompatPadding="true"
        card_view:cardCornerRadius="5dp">
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical"
            android:padding="8dp">
            <ImageView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/imageView"
                android:scaleType="centerCrop" />
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="#333333"
                android:text="Caption"
                android:id="@+id/textView"
                android:layout_gravity="center_horizontal"
                android:layout_marginLeft="4dp" />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</FrameLayout>

Questo layout rappresenta un singolo elemento di riga nell'oggetto RecyclerView. Il OnBindViewHolder metodo (descritto di seguito) copia i dati dall'origine dati in ImageView e TextView di questo layout. OnCreateViewHolder gonfia questo layout per una determinata posizione di foto in RecyclerView e crea un'istanza di una nuova PhotoViewHolder istanza (che individua e memorizza nella cache i riferimenti alle ImageView visualizzazioni figlio e TextView nel layout associato CardView ):

public override RecyclerView.ViewHolder
    OnCreateViewHolder (ViewGroup parent, int viewType)
{
    // Inflate the CardView for the photo:
    View itemView = LayoutInflater.From (parent.Context).
                Inflate (Resource.Layout.PhotoCardView, parent, false);

    // Create a ViewHolder to hold view references inside the CardView:
    PhotoViewHolder vh = new PhotoViewHolder (itemView);
    return vh;
}

L'istanza del titolare di visualizzazione risultante, vh, viene restituita al chiamante (gestione layout).

OnBindViewHolder

Quando il gestore layout è pronto per visualizzare una visualizzazione specifica nell'area RecyclerViewdello schermo visibile, chiama il metodo dell'adattatore OnBindViewHolder per riempire l'elemento nella posizione di riga specificata con contenuto dall'origine dati. OnBindViewHolder ottiene le informazioni sulla foto per la posizione di riga specificata (la risorsa immagine della foto e la stringa per la didascalia della foto) e copia questi dati nelle visualizzazioni associate. Le visualizzazioni si trovano tramite riferimenti archiviati nell'oggetto del supporto di visualizzazione (che viene passato tramite il holder parametro ):

public override void
    OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
{
    PhotoViewHolder vh = holder as PhotoViewHolder;

    // Load the photo image resource from the photo album:
    vh.Image.SetImageResource (mPhotoAlbum[position].PhotoID);

    // Load the photo caption from the photo album:
    vh.Caption.Text = mPhotoAlbum[position].Caption;
}

Prima di usarlo, è necessario eseguire il cast dell'oggetto porta vista passato nel tipo di supporto della vista derivata ( in questo caso , PhotoViewHolder). L'adattatore carica la risorsa immagine nella visualizzazione a cui fa riferimento la proprietà del Image titolare della visualizzazione e copia il testo della didascalia nella vista a cui fa riferimento la proprietà del Caption titolare della visualizzazione. In questo modo la vista associata viene associata ai relativi dati.

Si noti che OnBindViewHolder è il codice che gestisce direttamente la struttura dei dati. In questo caso, OnBindViewHolder viene illustrato come eseguire il mapping della posizione dell'elemento RecyclerView all'elemento di dati associato nell'origine dati. Il mapping è semplice in questo caso perché la posizione può essere usata come indice di matrice nell'album fotografico; Tuttavia, origini dati più complesse possono richiedere codice aggiuntivo per stabilire tale mapping.

ItemCount

Il ItemCount metodo restituisce il numero di elementi nella raccolta dati. Nell'app visualizzatore foto di esempio, il conteggio degli elementi è il numero di foto nell'album fotografico:

public override int ItemCount
{
    get { return mPhotoAlbum.NumPhotos; }
}

Per altre informazioni su , vedere le informazioni di riferimento sulla RecyclerView.Adapterclasse RecyclerView.Adapter.

Mettere tutto insieme

L'implementazione risultante RecyclerView per l'app foto di MainActivity esempio è costituita da codice che crea l'origine dati, il gestore layout e l'adattatore. MainActivity crea l'istanza mRecyclerView , crea un'istanza dell'origine dati e dell'adattatore e collega la gestione layout e l'adattatore:

public class MainActivity : Activity
{
    RecyclerView mRecyclerView;
    RecyclerView.LayoutManager mLayoutManager;
    PhotoAlbumAdapter mAdapter;
    PhotoAlbum mPhotoAlbum;

    protected override void OnCreate (Bundle bundle)
    {
        base.OnCreate (bundle);
        mPhotoAlbum = new PhotoAlbum();
        SetContentView (Resource.Layout.Main);
        mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);

        // Plug in the linear layout manager:
        mLayoutManager = new LinearLayoutManager (this);
        mRecyclerView.SetLayoutManager (mLayoutManager);

        // Plug in my adapter:
        mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
        mRecyclerView.SetAdapter (mAdapter);
    }
}

PhotoViewHolder individua e memorizza nella cache i riferimenti alla vista:

public class PhotoViewHolder : RecyclerView.ViewHolder
{
    public ImageView Image { get; private set; }
    public TextView Caption { get; private set; }

    public PhotoViewHolder (View itemView) : base (itemView)
    {
        // Locate and cache view references:
        Image = itemView.FindViewById<ImageView> (Resource.Id.imageView);
        Caption = itemView.FindViewById<TextView> (Resource.Id.textView);
    }
}

PhotoAlbumAdapter implementa i tre override obbligatori del metodo:

public class PhotoAlbumAdapter : RecyclerView.Adapter
{
    public PhotoAlbum mPhotoAlbum;
    public PhotoAlbumAdapter (PhotoAlbum photoAlbum)
    {
        mPhotoAlbum = photoAlbum;
    }

    public override RecyclerView.ViewHolder
        OnCreateViewHolder (ViewGroup parent, int viewType)
    {
        View itemView = LayoutInflater.From (parent.Context).
                    Inflate (Resource.Layout.PhotoCardView, parent, false);
        PhotoViewHolder vh = new PhotoViewHolder (itemView);
        return vh;
    }

    public override void
        OnBindViewHolder (RecyclerView.ViewHolder holder, int position)
    {
        PhotoViewHolder vh = holder as PhotoViewHolder;
        vh.Image.SetImageResource (mPhotoAlbum[position].PhotoID);
        vh.Caption.Text = mPhotoAlbum[position].Caption;
    }

    public override int ItemCount
    {
        get { return mPhotoAlbum.NumPhotos; }
    }
}

Quando questo codice viene compilato ed eseguito, crea l'app di visualizzazione foto di base, come illustrato negli screenshot seguenti:

Due screenshot dell'app di visualizzazione delle foto con schede fotografiche a scorrimento verticale

Se le ombreggiature non vengono disegnate (come illustrato nello screenshot precedente), modificare Proprietà/AndroidManifest.xml e aggiungere l'impostazione dell'attributo seguente all'elemento <application> :

android:hardwareAccelerated="true"

Questa app di base supporta solo l'esplorazione dell'album fotografico. Non risponde agli eventi di tocco degli elementi, né gestisce le modifiche nei dati sottostanti. Questa funzionalità viene aggiunta in Estensione dell'esempio RecyclerView.

Modifica di LayoutManager

Grazie alla RecyclerViewflessibilità, è facile modificare l'app per usare un gestore di layout diverso. Nell'esempio seguente viene modificato per visualizzare l'album fotografico con un layout griglia che scorre orizzontalmente anziché con un layout lineare verticale. A tale scopo, la creazione di un'istanza di Gestione layout viene modificata in modo da usare come GridLayoutManager segue:

mLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.Horizontal, false);

Questa modifica del codice sostituisce la verticale LinearLayoutManager con un oggetto GridLayoutManager che presenta una griglia costituita da due righe che scorrono nella direzione orizzontale. Quando si compila ed esegue di nuovo l'app, si noterà che le fotografie vengono visualizzate in una griglia e che lo scorrimento è orizzontale anziché verticale:

Screenshot di esempio dell'app con foto a scorrimento orizzontale in una griglia

Modificando una sola riga di codice, è possibile modificare l'app di visualizzazione foto per usare un layout diverso con un comportamento diverso. Si noti che non è stato necessario modificare né il codice dell'adattatore né il codice XML di layout per modificare lo stile di layout.

Nell'argomento successivo, Estensione dell'esempio RecyclerView, questa app di esempio di base viene estesa per gestire gli eventi di clic sugli elementi e aggiornare RecyclerView quando l'origine dati sottostante cambia.