Příklad základního objektu RecyclerView
Abyste pochopili, jak RecyclerView
funguje v typické aplikaci, toto téma zkoumá jednoduchý příklad kódu, který používá RecyclerView
k zobrazení velké kolekce fotek:
RecyclerViewer používá CardView k implementaci každé položky fotografie v RecyclerView
rozložení. RecyclerView
Vzhledem k výhodám výkonu je tato ukázková aplikace schopná rychle procházet velkou kolekci fotek hladce a bez znatelných zpoždění.
Příklad zdroje dat
V této ukázkové aplikaci zdroj dat "fotoalbum" (reprezentovaný PhotoAlbum
třídou) dodává RecyclerView
obsah položky.
PhotoAlbum
je kolekce fotek s titulky; když vytvoříte instanci, získáte připravenou kolekci 32 fotek:
PhotoAlbum mPhotoAlbum = new PhotoAlbum ();
Každá instance fotografie ve PhotoAlbum
vlastnostech zveřejňuje vlastnosti, které umožňují číst ID PhotoID
prostředku obrázku a jeho řetězec titulku, Caption
. Kolekce fotek je uspořádaná tak, aby každá fotka byla přístupná indexerem. Například následující řádky kódu přistupuje k ID prostředku obrázku a popisku desáté fotky v kolekci:
int imageId = mPhotoAlbum[9].ImageId;
string caption = mPhotoAlbum[9].Caption;
PhotoAlbum
také poskytuje metodu RandomSwap
, kterou můžete volat k prohození první fotky v kolekci s náhodně zvolenou fotkou jinde v kolekci:
mPhotoAlbum.RandomSwap ();
Vzhledem k tomu, že podrobnosti implementace PhotoAlbum
nejsou relevantní pro pochopení RecyclerView
, PhotoAlbum
zdrojový kód zde není uveden.
Rozložení a inicializace
Soubor rozložení Main.axml se skládá z jednoho RecyclerView
souboru v rámci LinearLayout
:
<?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>
Všimněte si, že musíte použít plně kvalifikovaný název android.support.v7.widget.RecyclerView , protože RecyclerView
je zabalený v knihovně podpory. Metoda OnCreate
MainActivity
inicializuje toto rozložení, vytvoří instanci adaptéru a připraví podkladový zdroj dat:
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);
Tento kód provádí následující úkony:
Vytvoří
PhotoAlbum
instanci zdroje dat.Předá zdroj dat fotoalba konstruktor adaptéru
PhotoAlbumAdapter
(který je definován dále v této příručce). Všimněte si, že se považuje za osvědčený postup předání zdroje dat jako parametr konstruktoru adaptéru.RecyclerView
Získá z rozložení.Připojí adaptér k
RecyclerView
instanci volánímRecyclerView
SetAdapter
metody, jak je znázorněno výše.
Správce rozložení
Každá položka v souboru RecyclerView
se skládá z CardView
obrázku fotky a titulku fotografie (podrobnosti jsou popsány v části Držitel zobrazení níže). Předdefinované LinearLayoutManager
se používá k rozložení každého CardView
ve svislém uspořádání posouvání:
mLayoutManager = new LinearLayoutManager (this);
mRecyclerView.SetLayoutManager (mLayoutManager);
Tento kód se nachází v metodě hlavní aktivity OnCreate
. Konstruktor pro správce rozložení vyžaduje kontext, takže se MainActivity
předává pomocí výše this
uvedeného příkladu.
Místo použití předdefinovaného LinearLayoutManager
objektu můžete připojit vlastního správce rozložení, který zobrazuje dvě CardView
položky vedle sebe, implementací animačního efektu s otáčením stránky pro procházení kolekcí fotek. Později v této příručce uvidíte příklad, jak upravit rozložení prohozením v jiném správci rozložení.
Zobrazit držák
Třída držáku zobrazení je volána PhotoViewHolder
. Každá PhotoViewHolder
instance obsahuje odkazy na ImageView
přidruženou položku řádku, TextView
která je rozložena v diagramu CardView
zde:
PhotoViewHolder
odvozuje a RecyclerView.ViewHolder
obsahuje vlastnosti pro uložení odkazů na ImageView
výše TextView
uvedené rozložení.
PhotoViewHolder
se skládá ze dvou vlastností a jednoho konstruktoru:
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);
}
}
V tomto příkladu PhotoViewHolder
kódu je konstruktor předán odkaz na zobrazení nadřazené položky (the CardView
), který PhotoViewHolder
se zabalí. Všimněte si, že nadřazené zobrazení položky vždy předáváte do základního konstruktoru. Konstruktor PhotoViewHolder
volá FindViewById
zobrazení nadřazené položky, aby vyhledaly všechny jeho podřízené odkazy ImageView
na zobrazení a TextView
uloží výsledky v Image
Caption
uvedeném pořadí. Adaptér později načte odkazy na zobrazení z těchto vlastností, když aktualizuje CardView
podřízená zobrazení s novými daty.
Další informace o RecyclerView.ViewHolder
, viz RecyclerView.ViewHolder třídy reference.
Adaptér
Adaptér načte každý RecyclerView
řádek s daty pro konkrétní fotografii. Pro danou fotografii na pozici řádku P například adaptér vyhledá přidružená data na pozici P ve zdroji dat a zkopíruje tato data do položky řádku na pozici P v kolekci RecyclerView
. Adaptér pomocí držáku zobrazení vyhledá odkazy na ImageView
danou a TextView
na této pozici, takže nemusí opakovaně volat FindViewById
tato zobrazení, protože uživatel prochází kolekcí fotografií a opakovaně používá zobrazení.
V RecyclerVieweru je třída adaptéru odvozena od RecyclerView.Adapter
vytvoření PhotoAlbumAdapter
:
public class PhotoAlbumAdapter : RecyclerView.Adapter
{
public PhotoAlbum mPhotoAlbum;
public PhotoAlbumAdapter (PhotoAlbum photoAlbum)
{
mPhotoAlbum = photoAlbum;
}
...
}
Člen mPhotoAlbum
obsahuje zdroj dat (fotoalbum), který je předán do konstruktoru; konstruktor zkopíruje fotoalbum do této členské proměnné. Implementují se následující požadované RecyclerView.Adapter
metody:
OnCreateViewHolder
– Vytvoří instanci souboru rozložení položky a držitele zobrazení.OnBindViewHolder
– Načte data na zadanou pozici do zobrazení, jejichž odkazy jsou uloženy v daném držiteli zobrazení.ItemCount
– Vrátí počet položek ve zdroji dat.
Správce rozložení volá tyto metody při umístění položek v rámci RecyclerView
. Implementace těchto metod je zkoumána v následujících částech.
OnCreateViewHolder
Správce rozložení volá OnCreateViewHolder
, když RecyclerView
potřebuje nového držitele zobrazení, aby představoval položku. OnCreateViewHolder
nafoukne zobrazení položky ze souboru rozložení zobrazení a zabalí zobrazení do nové PhotoViewHolder
instance. Konstruktor PhotoViewHolder
vyhledá a uloží odkazy na podřízená zobrazení v rozložení, jak je popsáno výše v nástroji View Holder.
Každá položka řádku je reprezentována položkou CardView
, která obsahuje ( ImageView
pro fotku) a ( TextView
pro titulek). Toto rozložení se nachází v souboru 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>
Toto rozložení představuje jednu položku řádku v objektu RecyclerView
. Metoda OnBindViewHolder
(popsaná níže) kopíruje data ze zdroje dat do ImageView
a TextView
z tohoto rozložení.
OnCreateViewHolder
nafoukne toto rozložení pro dané umístění fotky RecyclerView
v nové PhotoViewHolder
instanci (která vyhledá a ukládá odkazy na TextView
ImageView
podřízená zobrazení v přidruženém CardView
rozložení):
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;
}
Výsledná instance vh
držitele zobrazení se vrátí zpět volajícímu (správci rozložení).
OnBindViewHolder
Když je správce rozložení připravený k zobrazení určitého zobrazení v RecyclerView
oblasti viditelné obrazovky, zavolá metodu adaptéru OnBindViewHolder
, která vyplní položku na určené pozici řádku obsahem ze zdroje dat. OnBindViewHolder
získá informace o fotce pro zadanou pozici řádku (prostředek obrázku fotky a řetězec titulku fotky) a zkopíruje tato data do přidružených zobrazení. Zobrazení se nacházejí prostřednictvím odkazů uložených v objektu držáku zobrazení (který se předává prostřednictvím parametru holder
):
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;
}
Předaný objekt držáku zobrazení musí být nejprve přetypován na odvozený typ držáku zobrazení (v tomto případě PhotoViewHolder
) před jeho použitím.
Adaptér načte prostředek obrázku do zobrazení, na které odkazuje vlastnost držitele Image
zobrazení, a zkopíruje text titulku do zobrazení, na které odkazuje vlastnost držitele Caption
zobrazení. Tím se vytvoří vazba přidruženého zobrazení k datům.
Všimněte si, že OnBindViewHolder
je kód, který se zabývá přímo strukturou dat. V tomto případě se dozvíte, OnBindViewHolder
jak mapovat RecyclerView
pozici položky na přidruženou datovou položku ve zdroji dat. Mapování je v tomto případě jednoduché, protože pozici lze použít jako index pole do fotoalba; Složitější zdroje dat však mohou vyžadovat další kód pro vytvoření takového mapování.
ItemCount
Metoda ItemCount
vrátí počet položek v kolekci dat. V ukázkové aplikaci prohlížeče fotek je počet fotek v fotoalbu:
public override int ItemCount
{
get { return mPhotoAlbum.NumPhotos; }
}
Další informace o RecyclerView.Adapter
, naleznete v RecyclerView.Adapter třídy reference.
Seskupování všech
Výsledná RecyclerView
implementace ukázkové aplikace fotek se skládá z MainActivity
kódu, který vytvoří zdroj dat, správce rozložení a adaptér. MainActivity
mRecyclerView
vytvoří instanci, vytvoří instanci zdroje dat a adaptér a připojí správce rozložení a adaptér:
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
vyhledá a ukládá odkazy na zobrazení do mezipaměti:
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
implementuje tři přepsání požadované metody:
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; }
}
}
Když se tento kód zkompiluje a spustí, vytvoří základní aplikaci pro prohlížení fotek, jak je znázorněno na následujících snímcích obrazovky:
Pokud se stíny nevykreslují (jak vidíte na výše uvedeném snímku obrazovky), upravte Vlastnosti/AndroidManifest.xml a do elementu přidejte následující nastavení atributu <application>
:
android:hardwareAccelerated="true"
Tato základní aplikace podporuje pouze procházení fotoalba. Nereaguje na události, které se dotyknou položek, ani nezpracuje změny v podkladových datech. Tato funkce je přidána v rozšíření příkladu RecyclerView.
Změna správce rozložení
RecyclerView
Vzhledem k flexibilitě je snadné upravit aplikaci tak, aby používala jiného správce rozložení. V následujícím příkladu se upraví tak, aby zobrazovalo fotoalbum s rozložením mřížky, které se posunuje vodorovně místo svislého lineárního rozložení. K tomu je instance správce rozložení upravena tak, aby používala GridLayoutManager
následující:
mLayoutManager = new GridLayoutManager(this, 2, GridLayoutManager.Horizontal, false);
Tato změna kódu nahrazuje svislou LinearLayoutManager
GridLayoutManager
mřížku tvořenou dvěma řádky, které se posunou vodorovným směrem. Když aplikaci zkompilujete a spustíte znovu, uvidíte, že se fotky zobrazují v mřížce a že posouvání je vodorovné místo svislé:
Změnou pouze jednoho řádku kódu je možné upravit aplikaci pro prohlížení fotek tak, aby používala jiné rozložení s odlišným chováním. Všimněte si, že kód adaptéru ani kód XML rozložení se musel změnit tak, aby změnil styl rozložení.
V dalším tématu rozšíření příkladu RecyclerView je tato základní ukázková aplikace rozšířena tak, aby zpracovávala události kliknutí na položky a aktualizovala RecyclerView
se, když se podkladový zdroj dat změní.