Android的RecyclerView使用总结

2024-05-19 09:38

本文主要是介绍Android的RecyclerView使用总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言:

RecyclerView 小组件比 ListView 更高级且更具灵活性。 此小组件是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效的滚动操作。 如果您有数据集合,其中的元素将因用户操作或网络事件而发生改变,请使用RecyclerView 小组件。

RecyclerView  类别将通过提供下列功能简化庞大数据集的显示与处理:
用于项目定位的布局管理器
用于通用项目操作(例如删除或添加项目)的默认动画
您也可灵活选择如何为 RecyclerView 小组件定义定制布局管理器与动画。


如果要使用 RecyclerView  小组件,您必须指定一个适配器和一个布局管理器。 如果要创建一个适配器,请扩展 RecyclerView.Adapter  类别。

实现的详情将取决于数据集的具体信息以及视图的类型。 如果要了解更多信息,请参阅下列示例。

布局管理器将确定RecyclerView 内各项目视图的位置并决定何时重新使用用户已不可见的项目视图。 如果要重新使用(或重复使用)一个视图,布局管理器可能会要求适配器以数据集中的另一个元素替换视图的内容。 以此方式重复使用视图将可避免创建不必要的视图或执行成本高昂的 findViewById() 查找,从而改善性能。


RecyclerView  提供这些内置布局管理器:
LinearLayoutManager 以垂直或水平滚动列表方式显示项目。
GridLayoutManager 在网格中显示项目。
StaggeredGridLayoutManager 在分散对齐网格中显示项目。
如果要创建一个定制布局管理器,请扩展 RecyclerView.LayoutManager  类别。


动画
RecyclerView 在默认情况下启用增添与删除项目的动画。如果要定制这些动画,请扩展RecyclerView.ItemAnimator类别

并使用  RecyclerView.setItemAnimator()方法。


添加依赖项

RecyclerView小组件为 v7 支持内容库的一部分。 如果要在您的项目中使用这些小组件,请将 Gradle 依赖项添加至您的应用模块:

dependencies {...compile 'com.android.support:recyclerview-v7:21.0.+'
}


效果图:



RecyclerView解析

解析一:RecyclerView的基本使用(数据正常显示)

步骤一:编写布局(可以和listView对比来用)

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="0dp"
    android:layout_weight="8"
    android:id="@+id/rv"
    >
</android.support.v7.widget.RecyclerView>

步骤二:编写适配器

1>适配器需要继承RecyclerView.Adapter<MyAdapter.ViewHolder>

2>重写RecyclerView.Adapter<MyAdapter.ViewHolder>里边的三个方法:

onCreateViewHolder(ViewGroup parent, int viewType)
public void onBindViewHolder(final ViewHolder holder, int position)
public int getItemCount()

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {/***
     *所要展示的数据
     */
    private List<String> mDataset;

    /**
     * 构造函数
     * @param myDataset
     */
    public MyAdapter(List<String> myDataset) {mDataset = myDataset;
    }/**
     * 用于将布局载入ViewHolder里,实例化ViewHolder,并返回ViewHolder实例
     * @param parent
     * @param viewType
     * @return
     */
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_item_layout,parent,false);
        ViewHolder mViewHolder = new ViewHolder(v);
        return mViewHolder;
    }/**
     * 初始化子条目里边的控件
     * @param holder
     * @param position
     */
    @Override
    public void onBindViewHolder(final ViewHolder holder, int position) {holder.mTextView.setText(mDataset.get(position));
        if(listener != null){holder.mTextView.setOnClickListener(new View.OnClickListener() {@Override
                public void onClick(View v) {listener.onItemClick(v);
                }});

        }}/***
     * getItemCount()listView里边的getItemCount()方法所起作用一致,
     * 都是得到Adapter中所有条目的总数
     * @return
     */
    @Override
    public int getItemCount() {return mDataset.size();
    }/**
     * ViewHolder继承于RecyclerView.ViewHolder     * 然后在ViewHolder里边保存子条目的控件
     */
    class ViewHolder extends RecyclerView.ViewHolder{public TextView mTextView;
        public ViewHolder(View v) {super(v);
            mTextView = (TextView) v.findViewById(R.id.tv);
        }}}

步骤三:初始化数据和控件

主要是设置RecyclerView的适配器以及布局管理器

@Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    initData();

    initView();

}
/**
 * 构建数据
 */
private void initData() {mCityList.add("广州");
    mCityList.add("北京");
    mCityList.add("深圳");
    mCityList.add("上海");
    mCityList.add("杭州");
    mCityList.add("武汉");
    mCityList.add("天津");
    mCityList.add("重庆");
    mCityList.add("厦门");
    mCityList.add("香港");
    mCityList.add("福州");
    mCityList.add("南京");
    mCityList.add("苏州");
    mCityList.add("黄石");
    mCityList.add("大连");
    mCityList.add("丽江");
    mCityList.add("青岛");
    mCityList.add("重庆");
    mCityList.add("扬州");
    mCityList.add("澳门");
}
/**
 * 初始化控件
 */
public void initView(){mRecyclerView = (RecyclerView) findViewById(R.id.rv);

    /**
     * 指定一个布局管理器,在这里指定为LinearLayoutManager     * 若没有设置其排放的位置,则默认为竖直排放
     */
    mLayoutManager = new LinearLayoutManager(this);
    mRecyclerView.setLayoutManager(mLayoutManager);


    /**
     * 获取适配器
     */
    mAdapter = new MyAdapter(mCityList);

    /**
     * 设置RecyclerView的适配器
     */
    mRecyclerView.setAdapter(mAdapter);

}


解析二:布局管理器和动画

通过设置布局管理器,可以实现不同的展示效果,例如实现ListView的效果,GridView的效果,还有另外一种效果(自行体会)。

在代码的初始部分,布局管理器是需要进行设置的,否则,数据是不会显示出来的。例如:

/**
 * 指定一个布局管理器,在这里指定为LinearLayoutManager * 若没有设置其排放的位置,则默认为竖直排放
 */
mLayoutManager = new LinearLayoutManager(this);
mRecyclerView.setLayoutManager(mLayoutManager);


动画,主要是用在在删除条目或增加条目时,产生动画的效果,在代码中,不设置,则会使用系统默认的一种效果显示出来。

当然这个动画也可以自行去定义一个。但是在增删时,若想要看到动画效果,那么在添加数据时,需要用mAdapter.notifyItemInserted(index)

来替代mAdapter.notifyDataSetChanged()方法,在删除数据时,需要用mAdapter.notifyItemRemoved(index);来替代mAdapter.notifyDataSetChanged()

方法。例如:

/**
 * 设置动画,这里采用的是默认的一个动画,
 * 若不设置,也会使用这个默认的动画,当然也可以自行去定义动画。
 */
mRecyclerView.setItemAnimator(new DefaultItemAnimator());


解析三:分割线解析

分割线的实现,如下代码所示:

/**
 * 设置分割线
 */
mItemDecoration = new DividerItemDecoration(this, mCurrentOrientation);
mRecyclerView.addItemDecoration(mItemDecoration);

在这里,DividerItemDecoration类是需要我们自己去实现,它继承于RecyclerView.ItemDecoration,所以需要重写

其里边的方法,如下(参考官网Sample):

onDraw()主要用来实现分割线的绘制

@Override
public void onDraw(Canvas c, RecyclerView parent) {if (mOrientation == VERTICAL_LIST) {drawVertical(c, parent);
    } else {drawHorizontal(c, parent);
    }
}

getItemOffsets()主要是用来给绘制的分割线留出空间,

当然,也可以实现让 Item 与 其余 Item之间产生一定的间隔

@Override
public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) {int margin = (int) dimens*1;

    if (mOrientation == VERTICAL_LIST) {/**
         * Set the rectangle's coordinates to the specified values. Note: no range
         * checking is performed, so it is up to the caller to ensure that
         * left <= right and top <= bottom.
         *
         * @param left   The X coordinate of the left side of the rectangle
         * @param top    The Y coordinate of the top of the rectangle
         * @param right  The X coordinate of the right side of the rectangle
         * @param bottom The Y coordinate of the bottom of the rectangle
         */
        /**
         * 其实这一部分和设置Itemmargin效果一样,
         * 源码里边会把这一部分空间当做是系统已占用的空间,所以在绘制Item时,
         * 这一部分的是不会再被Item所利用的,而是空出来,由于分割线的绘制早于
         * Item的绘制,所以我们可以通过空出这么一部分信息,从而让分割线绘制的
         * 部分不被其余Item所占用。
         *
         * 在本示例中,我在布局文件中,把Itemmargin设置了 1dp ,
         * 而分割线是在Itemmargin下边绘制的,所以在本示例中,
         * 分割线会距离上边的Item 1dp 的间隔,与此同时,又由于分割线的高度为 4dp         * 所以在outRect.set(0, 0, 0, mDivider.getIntrinsicHeight() + margin)函数中,
         * 我通过也空出了分割线的高度 4dp ,然后还空出一个 1dp (int margin = (int) dimens*1;)         * 这样大家就可以观察到 在分割线的上方和下方,都会有一个 1dp 的空白间隔,这也就是
         * outRect.set(0, 0, 0, mDivider.getIntrinsicHeight() + margin)函数所起的作用,
         * 若将这个函数的参数全部设置为0,那么,Item是会覆盖掉分割线的,因为 Item的绘制晚于分割线的绘制;
         */
        outRect.set(0, 0, 0, mDivider.getIntrinsicHeight() + margin);
    } else {outRect.set(0, 0, mDivider.getIntrinsicHeight() + margin, 0);
    }
}

解析四:条目的侦听

在RecyclerView中,其是没有对 Item 的侦听的,所以需要我们自己用接口去实现,示例如下:

1>创建侦听接口用来给用户予以回调
public interface OnItemClickListen{void onItemClick(View v);
}

2>创建设置侦听接口的方法
public void setListener(OnItemClickListen listener){this.listener = listener;
}

3>当点击时,在里边调用侦听接口的方法
public void onBindViewHolder(final ViewHolder holder, int position) {holder.mTextView.setText(mDataset.get(position));
    if(listener != null){holder.mTextView.setOnClickListener(new View.OnClickListener() {@Override
            public void onClick(View v) {listener.onItemClick(v);
            }});

    }
}

4>若用户想要对 Item进行侦听,则需设置 侦听者(这个由调用者来实现)
/**
 * 自定义条目的侦听,因为默认情况下,
 * RecyclerView是没有对条目侦听的API的,
 * 需要自己去予以实现...
 */
mAdapter.setListener(new MyAdapter.OnItemClickListen(){@Override
    public void onItemClick(View v) {Toast.makeText(MainActivity.this,((TextView) v).getText(),Toast.LENGTH_SHORT).show();
    }
});


参考:

RecyclerView Training

RecyclerView API

深入理解 RecyclerView 系列之一:ItemDecoration


源码:

RecyclerView使用总结示例源码

这篇关于Android的RecyclerView使用总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/995778

相关文章

C语言中联合体union的使用

本文编辑整理自: http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=179471 一、前言 “联合体”(union)与“结构体”(struct)有一些相似之处。但两者有本质上的不同。在结构体中,各成员有各自的内存空间, 一个结构变量的总长度是各成员长度之和。而在“联合”中,各成员共享一段内存空间, 一个联合变量

关于C++中的虚拟继承的一些总结(虚拟继承,覆盖,派生,隐藏)

1.为什么要引入虚拟继承 虚拟继承是多重继承中特有的概念。虚拟基类是为解决多重继承而出现的。如:类D继承自类B1、B2,而类B1、B2都继承自类A,因此在类D中两次出现类A中的变量和函数。为了节省内存空间,可以将B1、B2对A的继承定义为虚拟继承,而A就成了虚拟基类。实现的代码如下: class A class B1:public virtual A; class B2:pu

Tolua使用笔记(上)

目录   1.准备工作 2.运行例子 01.HelloWorld:在C#中,创建和销毁Lua虚拟机 和 简单调用。 02.ScriptsFromFile:在C#中,对一个lua文件的执行调用 03.CallLuaFunction:在C#中,对lua函数的操作 04.AccessingLuaVariables:在C#中,对lua变量的操作 05.LuaCoroutine:在Lua中,

Vim使用基础篇

本文内容大部分来自 vimtutor,自带的教程的总结。在终端输入vimtutor 即可进入教程。 先总结一下,然后再分别介绍正常模式,插入模式,和可视模式三种模式下的命令。 目录 看完以后的汇总 1.正常模式(Normal模式) 1.移动光标 2.删除 3.【:】输入符 4.撤销 5.替换 6.重复命令【. ; ,】 7.复制粘贴 8.缩进 2.插入模式 INSERT

Lipowerline5.0 雷达电力应用软件下载使用

1.配网数据处理分析 针对配网线路点云数据,优化了分类算法,支持杆塔、导线、交跨线、建筑物、地面点和其他线路的自动分类;一键生成危险点报告和交跨报告;还能生成点云数据采集航线和自主巡检航线。 获取软件安装包联系邮箱:2895356150@qq.com,资源源于网络,本介绍用于学习使用,如有侵权请您联系删除! 2.新增快速版,简洁易上手 支持快速版和专业版切换使用,快速版界面简洁,保留主

如何免费的去使用connectedpapers?

免费使用connectedpapers 1. 打开谷歌浏览器2. 按住ctrl+shift+N,进入无痕模式3. 不需要登录(也就是访客模式)4. 两次用完,关闭无痕模式(继续重复步骤 2 - 4) 1. 打开谷歌浏览器 2. 按住ctrl+shift+N,进入无痕模式 输入网址:https://www.connectedpapers.com/ 3. 不需要登录(也就是

十五.各设计模式总结与对比

1.各设计模式总结与对比 1.1.课程目标 1、 简要分析GoF 23种设计模式和设计原则,做整体认知。 2、 剖析Spirng的编程思想,启发思维,为之后深入学习Spring做铺垫。 3、 了解各设计模式之间的关联,解决设计模式混淆的问题。 1.2.内容定位 1、 掌握设计模式的"道" ,而不只是"术" 2、 道可道非常道,滴水石穿非一日之功,做好长期修炼的准备。 3、 不要为了

Eclipse+ADT与Android Studio开发的区别

下文的EA指Eclipse+ADT,AS就是指Android Studio。 就编写界面布局来说AS可以边开发边预览(所见即所得,以及多个屏幕预览),这个优势比较大。AS运行时占的内存比EA的要小。AS创建项目时要创建gradle项目框架,so,创建项目时AS比较慢。android studio基于gradle构建项目,你无法同时集中管理和维护多个项目的源码,而eclipse ADT可以同时打开

android 免费短信验证功能

没有太复杂的使用的话,功能实现比较简单粗暴。 在www.mob.com网站中可以申请使用免费短信验证功能。 步骤: 1.注册登录。 2.选择“短信验证码SDK” 3.下载对应的sdk包,我这是选studio的。 4.从头像那进入后台并创建短信验证应用,获取到key跟secret 5.根据技术文档操作(initSDK方法写在setContentView上面) 6.关键:在有用到的Mo

android一键分享功能部分实现

为什么叫做部分实现呢,其实是我只实现一部分的分享。如新浪微博,那还有没去实现的是微信分享。还有一部分奇怪的问题:我QQ分享跟QQ空间的分享功能,我都没配置key那些都是原本集成就有的key也可以实现分享,谁清楚的麻烦详解下。 实现分享功能我们可以去www.mob.com这个网站集成。免费的,而且还有短信验证功能。等这分享研究完后就研究下短信验证功能。 开始实现步骤(新浪分享,以下是本人自己实现