Android-RecyclerView

  • RecyclerView要求|概述
  • 部件和功能
  • RecyclerView示例
  • 擴展示例

 

 
RecyclerView 是用於顯示集合的視圖組;它旨在爲早期視圖組(如 ListView 和 GridView)提供更靈活的替換。 本指南說明如何在 Xamarin Android 應用程序中使用和自定義 RecyclerView。

RecyclerView

許多應用程序都需要顯示相同類型的集合(如消息、聯繫人、圖像或歌曲);通常,此集合太大而無法放在屏幕上,因此集合顯示在一個小窗口中,可以平滑滾動集合中的所有項。 RecyclerView 是一種 Android 小組件,用於顯示列表或網格中的項集合,使用戶能夠滾動瀏覽集合。 下面是一個示例應用程序的屏幕截圖,使用 RecyclerView 在垂直滾動列表中顯示電子郵件收件箱內容:

使用 RecyclerView 列出收件箱消息的信息。

 

 

RecyclerView 提供了兩個引人注目的功能:

  • 它具有靈活的體系結構,使你能夠通過插入首選組件來修改其行爲。
  • 這種方法對大型集合非常有效,因爲它會重用項視圖,並要求使用視圖持有者來緩存視圖引用。

本指南說明如何在 Xamarin Android 應用程序中使用 RecyclerView;其中介紹瞭如何將 RecyclerView 包添加到你的 Xamarin Android 項目,並介紹瞭如何在典型的應用程序中使用 RecyclerView 功能。 提供了代碼示例,用於演示如何將 RecyclerView 集成到應用程序中,如何實現項-視圖單擊,以及如何在基礎數據更改時刷新 RecyclerView。 本指南假定你熟悉 Xamarin Android 開發。

要求

儘管 RecyclerView 通常與 Android 5.0 棒糖形關聯,但它作爲支持庫提供 – RecyclerView 適用於面向 API 級別7(Android 2.1)和更高版本的應用。 在基於 Xamarin 的應用程序中使用 RecyclerView 需要以下各項:

  • Xamarin – xamarin 4.20 或更高版本必須安裝並配置 Visual Studio 或 Visual Studio for Mac。
  • 應用項目必須包含v7. RecyclerView包。 有關安裝 NuGet 包的詳細信息,請參閱演練:在項目中包括 NuGet

概述

RecyclerView 可以被視爲 Android 中 ListView 和 GridView 小組件的替換。 與前置任務一樣,RecyclerView 旨在在小窗口中顯示大型數據集,但 RecyclerView 提供更多佈局選項,並且更適合用於顯示大集合。 如果你熟悉 ListViewListView 和 RecyclerView之間有幾個重要的區別:

  • 使用 RecyclerView 稍微複雜一些:您必須編寫更多的代碼,RecyclerView 以便與 ListView進行比較。
  • RecyclerView 不提供預定義的適配器;必須實現訪問數據源的適配器代碼。 但是,Android 包含多個預定義的適配器,它們使用 ListView 和 GridView
  • 當用戶點擊某個項時,RecyclerView 不會提供項單擊事件;相反,項單擊事件由 helper 類處理。 與此相反,ListView 提供一項 click 事件。
  • RecyclerView 通過回收視圖和強制使用視圖持有者模式來增強性能,從而消除了不必要的佈局資源查找。 在 ListView中,使用 "查看者" 模式是可選的。
  • RecyclerView 基於模塊化設計,使其更易於自定義。 例如,你可以插入不同的佈局策略,而不會對應用進行重大的代碼更改。 與此相反,ListView 在結構上相對單一。
  • RecyclerView 包括項 "添加" 和 "移除" 的內置動畫。 在應用程序開發人員的部分,ListView 動畫需要額外的工作。

 

RecyclerView 部件和功能

RecyclerView在內部處理某些任務(如視圖的滾動和回收),但是它實質上是協調 helper 類以顯示集合的管理器。 RecyclerView將任務委託給以下幫助程序類:

  • Adapter–增加項佈局(實例化佈局文件的內容),並將數據綁定到顯示的視圖 RecyclerView 中。 適配器還會報告項目單擊事件。
  • LayoutManager–度量和定位中的項視圖 RecyclerView ,並管理視圖回收策略。
  • ViewHolder–查找並存儲視圖引用。 視圖刀柄還有助於檢測項目-查看單擊。
  • ItemDecoration–允許應用向特定視圖添加特殊的繪圖和佈局偏移量,以便在項、突出顯示和視覺分組邊界之間繪製分隔線。
  • ItemAnimator–定義在項操作期間或對適配器進行更改時所發生的動畫。

RecyclerView LayoutManager Adapter 下圖描述了、和類之間的關係:

包含 LayoutManager 的 RecyclerView 关系图,使用适配器访问数据集

如圖所示, LayoutManager 可以視爲Adapter RecyclerView之間的中介  LayoutManager Adapter 可代表調用方法 RecyclerView 。 例如, LayoutManager Adapter 當需要爲特定項位置創建新的視圖時,將調用方法 RecyclerView  Adapter增加該項目的佈局,並創建 ViewHolder 實例(未顯示)來緩存對該位置的視圖的引用。 當 LayoutManager 調用將 Adapter 特定項綁定到數據集時,將爲 Adapter 該項定位數據,從數據集中檢索數據,並將其複製到關聯的項視圖。

RecyclerView在應用中使用時,需要創建以下類的派生類型:

  • RecyclerView.Adapter–提供從應用程序的數據集(特定於您的應用程序)到 RecyclerView中顯示的項視圖的綁定 。 適配器知道如何將 RecyclerView 中的每個項視圖位置與數據源中的特定位置相關聯。 此外,適配器還處理每個單獨項視圖中內容的佈局,併爲每個視圖創建視圖佔位符。 適配器還會報告項目視圖檢測到的項目單擊事件。
  • RecyclerView.ViewHolder–緩存對項佈局文件中的視圖的引用,以避免不必要地重複資源查找。 視圖容納器還會安排在用戶點擊視圖持有者的關聯項視圖時,將其轉發到適配器。
  • RecyclerView.LayoutManager–定位RecyclerView中的項  。 您可以使用幾個預定義的佈局管理器之一,也可以實現您自己的自定義佈局管理器。 RecyclerView將佈局策略委託給佈局管理器,這樣您就可以插入不同的佈局管理器,而無需對應用進行重大更改。

此外,還可以選擇擴展以下類,以更改 RecyclerView 應用中的外觀:

  • RecyclerView.ItemDecoration
  • RecyclerView.ItemAnimator

如果未擴展 ItemDecoration 和ItemAnimator,則 ItemAnimator RecyclerView 使用默認實現。 本指南不介紹如何創建自定義 ItemDecoration 類和 ItemAnimator 類; 有關這些類的詳細信息,請參閱RecyclerView. ItemDecoration and RecyclerView

 

視圖回收的工作原理

RecyclerView不會爲數據源中的每個項分配項視圖。 相反,它僅分配適合屏幕的項視圖數,並在用戶滾動時重用這些項佈局。 當視圖第一次滾動時,它會經歷下圖所示的回收過程:
说明查看回收的六个步骤的示意图
  1. 當視圖在視覺上滾動並不再顯示時,它將成爲一個廢料視圖
  2. "碎片" 視圖放置在一個池中,併成爲回收視圖。 此池是顯示相同數據類型的視圖緩存。
  3. 當顯示新項時,將從回收池中獲取視圖以供重用。 因爲此視圖必須在適配器重新綁定後才能顯示,所以稱爲 "髒視圖"。
  4. 已回收髒視圖:適配器查找要顯示的下一項的數據,並將此數據複製到此項的視圖。 這些視圖的引用將從與回收視圖關聯的視圖持有者中進行檢索。
  5. 回收視圖將添加到RecyclerView 中的項的列表中,這些項將在屏幕上進行。
  6. 當用戶將滾動 RecyclerView 到列表中的下一項時,回收視圖將在屏幕上顯示。 同時,另一個視圖會滾動顯示,並根據以上步驟進行回收。

除項-視圖重用外, RecyclerView 還使用另一個效率優化:查看持有者。 視圖佔位符是緩存視圖引用的簡單類。 每次適配器增加項佈局文件時,它也會創建相應的視圖持有者。 視圖佔位符用於 FindViewById 獲取對放大項-佈局文件內的視圖的引用。 每次回收佈局以顯示新數據時,這些引用用於將新數據加載到視圖中。

佈局管理器

佈局管理器負責在顯示中定位項 RecyclerView ; 它確定表示類型(列表或網格)、方向(項是垂直顯示還是水平顯示)以及應顯示的方向項(按正常順序或逆序顯示)。 佈局管理器還負責計算RecycleView顯示中每個項的大小和位置。

佈局管理器有一個額外的用途:它確定何時回收不再向用戶顯示的項視圖的策略。 由於佈局管理器識別哪些視圖是可見的(而不是),因此,它在確定何時可以回收視圖的最佳位置。 若要回收視圖,佈局管理器通常會調用適配器,以將回收視圖的內容替換爲不同的數據,如前面的視圖回收的工作原理中所述。

您可以擴展 RecyclerView.LayoutManager 以創建自己的佈局管理器,也可以使用預定義的佈局管理器。 RecyclerView提供以下預定義的佈局管理器:

  • LinearLayoutManager–對可垂直滾動的列中的項或在可水平滾動的行中進行排列。
  • GridLayoutManager–在網格中顯示項。
  • StaggeredGridLayoutManager–顯示分散網格中的項,其中某些項具有不同的高度和寬度。

若要指定佈局管理器,請實例化所選的佈局管理器,並將其傳遞給 SetLayoutManager 方法。 請注意,在默認情況下,必須指定佈局管理器 – RecyclerView 未選擇預定義的佈局管理器。

有關佈局管理器的詳細信息,請參閱RecyclerView. LayoutManager 類引用

視圖持有者

視圖佔位符是您爲緩存視圖引用定義的類。 適配器使用這些視圖引用將每個視圖綁定到其內容。 RecyclerView中的每個項都有一個關聯的視圖持有者實例,該實例將緩存該項的視圖引用。 若要創建視圖持有者,請使用以下步驟來定義一個類,以便保存每個項目的確切視圖集:

  1. 子類 RecyclerView.ViewHolder 。
  2. 實現一個查找並存儲視圖引用的構造函數。
  3. 實現適配器可用於訪問這些引用的屬性。

ViewHolder基本 RecyclerView 示例中提供了實現的詳細示例。 有關的詳細信息 RecyclerView.ViewHolder ,請參閱RecyclerView. ViewHolder 類引用

適配器

集成代碼的大部分 "繁重" 操作 RecyclerView 都在適配器中進行。 RecyclerView要求你提供從派生的適配器 RecyclerView.Adapter 以訪問數據源,並使用數據源中的內容填充每個項。 由於數據源是特定於應用的,因此你必須實現可瞭解如何訪問數據的適配器功能。 適配器從數據源中提取信息,並將其加載到集合中的每個項 RecyclerView

下圖說明了適配器如何將數據源中的內容映射到RecyclerView中的每個行項內的各個視圖:

 

 

 

 

適配器 RecyclerView 使用特定行項的數據加載每一行。 例如,對於行位置p,適配器會在數據源中的位置p找到關聯的數據,並將此數據複製到集合中位於p位置的行項 RecyclerView 。 例如,在上面的繪圖中,適配器使用視圖持有者在該位置查找和的引用 ImageView , TextView 因此, FindViewById 當用戶滾動集合並重復使用視圖時,無需重複調用這些視圖。

實現適配器時,必須重寫以下 RecyclerView.Adapter 方法:

  • OnCreateViewHolder–實例化項佈局文件和視圖持有者。
  • OnBindViewHolder 將 – 位於指定位置的數據加載到其引用存儲在給定視圖持有者中的視圖中。
  • ItemCount–返回數據源中的項數。

佈局管理器在定位中的項時調用這些方法 RecyclerView 。

 

向 RecyclerView 通知數據更改

RecyclerView不會在其數據源的內容更改時自動更新其顯示;數據集發生更改時,適配器必鬚髮出通知 RecyclerView 。 數據集可以通過多種方式進行更改;例如,項目中的內容可能會更改,或者可能會更改數據的整體結構。 RecyclerView.Adapter提供了許多方法,您可以調用這些方法以 RecyclerView 最有效的方式響應數據更改:

  • NotifyItemChanged–指示位於指定位置處的項已更改。
  • NotifyItemRangeChanged–指示指定位置範圍內的項已更改。
  • NotifyItemInserted–指示指定位置中的項已新插入。
  • NotifyItemRangeInserted–指示指定位置範圍內的項已新插入。
  • NotifyItemRemoved–指示已刪除指定位置中的項。
  • NotifyItemRangeRemoved–指示已刪除指定範圍內的項。
  • NotifyDataSetChanged–通知數據集已更改(強制執行完全更新)。

如果確切知道數據集的更改方式,則可以調用上述相應方法,以 RecyclerView 最有效的方式進行刷新。 如果你不確切地知道數據集的更改方式,則可以調用 NotifyDataSetChanged ,這種方式要低得多,因爲 RecyclerView 必須刷新對用戶可見的所有視圖。 有關這些方法的詳細信息,請參閱RecyclerView

下一主題是一個基本的 RecyclerView 示例,它是一個示例應用程序,用於演示上述部分和功能的實際代碼示例。

 


基本 RecyclerView 示例

爲了瞭解 RecyclerView 典型應用程序中的工作原理,本主題介紹了RecyclerViewer示例應用,這是一個用於 RecyclerView 顯示大量照片的簡單代碼示例:

 

 

RecyclerViewer使用CardView實現佈局中的每個照片項 RecyclerView 。 由於性能方面的 RecyclerView 優勢,此示例應用程序能夠快速滾動大量照片,而不會出現明顯的延遲。

示例數據源

在此示例應用程序中,"相冊" 數據源(由類表示 PhotoAlbum )提供 RecyclerView 了項內容。 PhotoAlbum帶有字幕的照片集合;當你對其進行實例化時,將獲得一個現成的32照片集合:
PhotoAlbum mPhotoAlbum = new PhotoAlbum ();
 PhotoAlbum 中的每個照片實例都公開了屬性,這些屬性允許您讀取其圖像資源 ID 及其 PhotoID 標題字符串 Caption 。 照片集合經過組織,可以通過索引器訪問每張照片。 例如,以下代碼行訪問集合中第十張照片的圖像資源 ID 和標題:
int imageId = mPhotoAlbum[9].ImageId;
string caption = mPhotoAlbum[9].Caption;
PhotoAlbum還提供了一個 RandomSwap 方法,可以調用該方法,將集合中的第一個照片替換爲集合中其他位置隨機選擇的照片:
mPhotoAlbum.RandomSwap ();
由於 PhotoAlbum 的實現細節與RecyclerView理解無關 ,因此 PhotoAlbum 此處不會顯示源代碼。 PhotoAlbum RecyclerViewer示例應用程序的PhotoAlbum.cs中提供了源代碼。

佈局和初始化

佈局文件main.axml包含RecyclerView中的單個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>
請注意,必須使用完全限定的名稱v7 ,因爲 RecyclerView 會打包到支持庫中。 MainActivity 的 OnCreate 方法初始化此佈局,實例化適配器,並準備基礎數據源:
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 ();
 
        // 實例化適配器並傳入其數據源:
        mAdapter = new PhotoAlbumAdapter (mPhotoAlbum);
 
        // 從“主”佈局資源設置視圖:
        SetContentView (Resource.Layout.Main);
 
        // 獲取我們的回收視圖佈局:
        mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);
 
        // 將適配器插入回收視圖:
        mRecyclerView.SetAdapter (mAdapter);

此代碼將執行以下操作:

  1. 實例化 PhotoAlbum 數據源。
  2. 將唱片集數據源傳遞到適配器的構造函數 PhotoAlbumAdapter(在本指南的後面部分中定義)。 請注意,將數據源作爲參數傳遞給適配器的構造函數是一種最佳做法。
  3. RecyclerView從佈局中獲取。
  4. RecyclerView通過調用RecyclerView SetAdapter方法將適配器插入到實例中,如上面所示。

佈局管理器

RecyclerView中的每一項都由一個 CardView 包含照片圖像和照片標題的組成(詳細信息將在下面的 "查看容器" 部分中介紹)。 預定義 LinearLayoutManager 用於 CardView 在垂直滾動排列中佈局每個:
mLayoutManager = new LinearLayoutManager (this);
mRecyclerView.SetLayoutManager (mLayoutManager);

此代碼位於主活動的OnCreate方法中。 佈局管理器的構造函數需要上下文,因此 MainActivity 使用傳遞的是this, 如上所述。

可以不使用預定義的,而是 LinearLayoutManager 插入一個自定義的佈局管理器,該管理器將並排顯示兩個 CardView 項,實現頁面翻轉動畫效果以遍歷照片集。 稍後在本指南中,你將看到一個示例,說明如何通過在不同的佈局管理器中進行交換來修改佈局。

查看刀柄

調用視圖持有者類 PhotoViewHolder 。 每個 PhotoViewHolder 實例都包含對 ImageView 關聯行項的和TextView的引用,這些行項在CardView中按圖解的方式進行佈局

 

 

PhotoViewHolder派生自 RecyclerView.ViewHolder ,其中包含用於存儲對ImageView和TextView的引用並顯示在上述佈局中的屬性。PhotoViewHolder包含兩個屬性和一個構造函數:
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);
    }
}

在此代碼示例中, PhotoViewHolder 構造函數向包裝的父項視圖 PhotoViewHolder()傳遞引用 CardView 。 請注意,始終將父項視圖轉發到基構造函數。 PhotoViewHolder構造函數對 FindViewById 父項視圖調用以定位其每個子視圖引用, ImageView 並分別將 TextView 結果存儲在 Image 和Caption 屬性中。 以後,適配器將在用新數據更新此子視圖時從這些屬性中檢索視圖引用 CardView 。

有關的詳細信息 RecyclerView.ViewHolder ,請參閱RecyclerView. ViewHolder 類引用

適配器

適配器 RecyclerView 使用特定照片的數據加載每一行。 例如,對於位於第p行的給定照片,適配器會在數據源中的位置p找到關聯的數據,並將此數據複製到集合中位於p位置的行項 RecyclerView 。 適配器使用視圖持有者在該位置查找和的引用 ImageView , TextView 這樣 FindViewById 當用戶滾動照片集合並重復使用視圖時,無需重複調用這些視圖。

RecyclerViewer中,適配器類從RecyclerView.Adapter派生,以創建 PhotoAlbumAdapter :

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

mPhotoAlbum成員包含傳入構造函數的數據源(相冊); 構造函數將相冊複製到此成員變量中。 實現以下必需 RecyclerView.Adapter 方法:

  • OnCreateViewHolder–實例化項佈局文件和視圖持有者。
  • OnBindViewHolder 將 – 位於指定位置的數據加載到其引用存儲在給定視圖持有者中的視圖中。
  • ItemCount–返回數據源中的項數。

佈局管理器在定位 RecyclerView 中的項時調用這些方法。 以下各節將對這些方法的實現進行了檢查。

 

OnCreateViewHolder

當 RecyclerView 需要新的視圖持有者來表示項時,佈局管理器會調用OnCreateViewHolder。 OnCreateViewHolder從視圖的佈局文件中增加項視圖,並在新的實例中包裝視圖 PhotoViewHolder 。PhotoViewHolder構造函數在佈局中查找並存儲對子視圖的引用,如前面的 "查看容器" 中所述。

每個行項由一個 CardView 包含 ImageView (對於照片)和一個 TextView (用於標題)的表示。 此佈局位於 PhotoCardView 文件中 。 main.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>
此佈局表示 RecyclerView中的單個行項 。 OnBindViewHolder方法(如下所述)將數據從數據源複製到此佈局的 ImageView 和 TextView 中。OnCreateViewHolder爲 RecyclerView 中的給定照片位置增加此佈局,並實例化一個新 PhotoViewHolder 實例(該實例在關聯佈局中查找並緩存對 ImageView 和 TextView 子視圖的引用 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;
}
生成的視圖持有者實例 vh 返回到調用方(佈局管理器)。

OnBindViewHolder

當佈局管理器準備好在的可視屏幕區域中顯示特定視圖時 RecyclerView ,它會調用適配器的 OnBindViewHolder 方法,以使用來自數據源的內容來填充位於指定行位置的項。 OnBindViewHolder獲取指定行位置(照片的圖像資源和照片標題的字符串)的照片信息,並將此數據複製到關聯的視圖中。 視圖通過存儲在視圖容器對象中的引用來定位(通過 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;
}

使用傳入的視圖持有者對象之前,必須先將該對象強制轉換爲派生的視圖持有者類型(在本例中爲 PhotoViewHolder )。 適配器將圖像資源加載到視圖持有者的屬性所引用的視圖 Image 中,並將標題文本複製到視圖持有者的屬性所引用的視圖 Caption中 。 這會將關聯視圖與其數據綁定在一起。

注意: OnBindViewHolder 是直接處理數據結構的代碼。 在這種情況下, OnBindViewHolder 瞭解如何將 RecyclerView 項位置映射到數據源中其關聯數據項。 在這種情況下,映射很簡單,因爲位置可用作相冊中的數組索引;但是,更復雜的數據源可能需要額外的代碼來建立此類映射。

ItemCount

ItemCount方法返回數據集合中的項數。 在示例照片查看器應用程序中,項計數是相冊中照片的數目:

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

有關的詳細信息 RecyclerView.Adapter ,請參閱RecyclerView 類引用

將其全部放在一起

RecyclerView示例照片應用程序的結果實現包括 MainActivity 創建數據源、佈局管理器和適配器的代碼。 MainActivity創建 mRecyclerView實例,實例化數據源和適配器,並插入佈局管理器和適配器:

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查找並緩存視圖引用:

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實現三個所需的方法重寫:

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; }
    }
}
編譯並運行此代碼時,它將創建基本照片查看應用,如以下屏幕截圖所示:

 

 


 

 

如果未繪製陰影(如上面的屏幕截圖所示),請編輯Properties/androidmanifest.xml ,並將以下屬性設置添加到 <application> 元素:
android:hardwareAccelerated="true"
此基本應用僅支持瀏覽相冊。 它不響應項觸控事件,也不處理基礎數據中的更改。 此功能是在擴展 RecyclerView 示例中添加的。

更改 LayoutManager

由於 RecyclerView 非常靈活,因此可輕鬆修改應用以使用不同的佈局管理器。 在下面的示例中,將對其進行修改,以顯示帶有水平滾動而不是垂直線性佈局的網格佈局的相冊。 爲此,佈局管理器實例化將被修改爲使用,如下所示 GridLayoutManager :

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

 

此代碼更改將垂直替換爲 LinearLayoutManager 一個 GridLayoutManager ,它表示由兩行組成的網格,該網格沿水平方向滾動。 再次編譯並運行應用程序時,將看到照片顯示在網格中,並且滾動是水平而不是垂直的:

通過只更改一行代碼,可以修改照片查看應用程序,以使用具有不同行爲的不同佈局。 請注意,適配器代碼和佈局 XML 都必須修改以更改佈局樣式。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章