zoukankan      html  css  js  c++  java
  • 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 都必须修改以更改布局样式。

    
    
  • 相关阅读:
    如何设计一个百万级用户的抽奖系统?
    服务注册发现
    消息列队7
    消息列队6
    bzoj 4771: 七彩树
    [SDOI2013]刺客信条
    bzoj 5291: [Bjoi2018]链上二次求和
    51nod 1245 Binomial Coefficients Revenge
    bzoj 5308: [Zjoi2018]胖
    bzoj 5294: [Bjoi2018]二进制
  • 原文地址:https://www.cnblogs.com/Chestnut-g/p/14173897.html
Copyright © 2011-2022 走看看