Android开发——RecyclerView特性以及基本使用方法(一)
0. 前言
随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用。但显然并不能说RecyclerView就一定优于ListView,而是应该根据不同的需求选择最合适的进行使用。本篇将介绍我们为什么要使用RecyclerView,并且它的基本使用方法。
本文原创,转载请注明出处为SEU_Calvin的博客。
1. 我们为什么要使用RecyclerView
Google声称你可以把RecyclerView看成是升级版的ListView,为什么ListView没有被遗弃呢?到底RecyclerView强在哪里了呢?
其实如果你只想简单的使用滑动显示这个功能,并且想轻松的使用divider,header,footer或者点击事件这些功能,那么使用ListView是完全没有问题的。RecyclerView除了已经封装好的Item复用机制外,的重点应该放在灵活性上,高度的解耦,这使得RecyclerView能够实现深度的定制化,通过提供的不同LayoutManager,ItemDecoration,ItemAnimator等可以实现很多的效果。
(1)RecyclerView提供的三种布局管理器(LayoutManager),可以无缝衔接ListView、GridView,瀑布流的实现也变得简单,滑动删除和长按交换只需要添加几个类就可以实现。
(2)ListView只有一个notifyDatasetChanged方法,想要做局部刷新还是挺麻烦的,但是在RecyclerView中,有很多适配局部刷新的API。
(3)RecyclerView实现Item增删等动画效果时,因为有了ItemAnimator因此要比ListView简单的多。如果想定制Item之间的间隔,使用ItemDecoration也很方便。
(4)关于点击事件,没有像ListView那样现成的API,但是自己封装起来也不难,而且我们使用ListView时,如果item中有可点击组件,那么点击事件的冲突也是一个问题,而在RecyclerView中则把点击事件的控制权完全的交给开发者。
2. RecyclerView的简单使用
2.1 Adapter中的实现
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
//…
}
RecyclerView的Adapter需要继承RecyclerView.Adapter<RecyclerAdapter.ViewHolder>
其中有几个比较重要的方法需要实现,分别如下所示:
@Override
public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
if (TYPE_ITEM == viewType) {
View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
return new ViewHolder(v);
} else {
View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_footer, viewGroup, false);
return new ViewHolder(view);
}
} @Override
public void onBindViewHolder(ViewHolder viewHolder, int i) {
viewHolder.textView.setText(mData.get(i) + i);
} @Override
public int getItemCount() {
return mData.size();
}
其中onCreateViewHolder()将布局转化为View并传递给RecyclerView封装好的ViewHolder,为了展示在RecyclerView中展示两种布局的方式,做了两种区分,即如果是RecyclerView的最后一个条目,则换一种布局展示。这里简单的设置两个布局xml只是背景颜色不同,因此可以返回一样的ViewHolder。而正常情况下可以新建另一个内部类FooterViewHolder extendsRecyclerView.ViewHolder,并在onCreateViewHolder()中进行区分返回。而这个例子中我们返回的ViewHolder是一个内部类。在其中进行控件的初始化。
public class ViewHolder extends RecyclerView.ViewHolder{
        public TextView textView;
        public ViewHolder(View itemView) {
            super(itemView);
            textView = (TextView)itemView.findViewById(R.id.id_num);
        }
}
在onCreateViewHolder(ViewGroup viewGroup, int viewType)中的第二个参数,就是进行类别区分的,和ListView类似,需要在Adapter内部重写getItemViewType(intposition) 方法,实现哪个位置需要加载哪种布局的逻辑。如下例中,如果是最后一个条目,则返回一个代号。用于onCreateViewHolder()方法中进行具体的布局加载。
@Override
public int getItemViewType(int position) {
if (position + 1 == getItemCount()) {
return TYPE_FOOTER;
} else {
return TYPE_ITEM;
}
}
有了ViewHolder之后,接下来就是要将ViewHolder和数据给绑定到一起来,在必须要实现的第二个方法onBindViewHolder(ViewHolder viewHolder,int i)中则建立起ViewHolder中视图与数据的关联。参数一个为对应的ViewHolder,一个为对应的位置。显然如果需要展示不同的布局,在onBindViewHolder()中通过判断viewHolder instanceof ViewHolder进行区分,对不同的布局中不同视图进行不同的数据关联。
最后getItemCount()是告知RecycleView,此Adapter到底要处理多少个对象。
2.2 Activity中的实现
mRcList = (RecyclerView) findViewById(R.id.rc_list);
mLayoutManager = new LinearLayoutManager(this);
mRcList.setLayoutManager(mLayoutManager);
mRcList.setHasFixedSize(true);
mSpinner = (Spinner) findViewById(R.id.spinner);
mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if (position == 0) {
mRcList.setLayoutManager(new LinearLayoutManager(MainActivity.this));
//设置分隔线
mRcList.addItemDecoration(new DividerItemDecoration(MainActivity.this, DividerItemDecoration.VERTICAL));
} else if (position == 1) {
mRcList.setLayoutManager(new GridLayoutManager(MainActivity.this, 3));
mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
}else if(position == 2){
//代表横着有10行
mRcList.setLayoutManager(new StaggeredGridLayoutManager(10,StaggeredGridLayoutManager.HORIZONTAL));
mRcList.addItemDecoration(new DividerGridItemDecoration(MainActivity.this));
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
这里需要说明的是,现在SDK中提供了三种LayoutManager可以提供给RecyclerView使用,分别为LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager。本例中使用一个Spinner实现一个动态的切换效果。
在设置的分隔线时,LinearLayoutManager设置为了系统默认的分隔线,如12行所示。如果想自定义,则可以在style中加入<item name="android:listDivider">@drawable/divider</item>,并在divider.xml中自行绘制矩形。而后两种布局中,默认的分割线是不合适的,DividerGridItemDecoration是自定义的。主要判断如果是最后一行,则不需要绘制底部;如果是最后一列,则不需要绘制右边,整个判断也考虑到了StaggeredGridLayoutManager的横向和纵向,所以稍稍有些复杂。有兴趣的可以在源码中自行解读。
mRcList.setHasFixedSize(true)的作用查了一下,解释如下:
//setHasFixedSize() is used to let the RecyclerView keep the same size.
//This information will be used to optimize itself.
最后进行数据初始化以及设置Adapter:
for(int i=0; i<=20 ; i++){
    mData.add("Recycler");
}
mAdapter = new RecyclerAdapter(mData);
mRcList.setAdapter(mAdapter);
从效果图中可以看到,使用RecyclerView实现了两种不同的布局,通过背景颜色进行区分。而且,可以动态的为RecyclerView设置三种不同的布局。并且当点击主界面的删除按钮时,实现了删除最后一个Item的操作,这里notifyDataSetChanged()是通知Adapter数据发生了改变。
public void delRecycler(View view) {
        if (mData.size()> 0) {
            mData.remove(mData.size()- 1);
            mAdapter.notifyDataSetChanged();
        }
}
关于RecyclerView动画效果以及点击事件的设置方法,在Android开发——RecyclerView特性以及基本使用方法(二)中进行介绍。
Android开发——RecyclerView特性以及基本使用方法(一)的更多相关文章
- Android开发——RecyclerView特性以及基本使用方法(二)
		
0. 前言 随着Android的发展,虽然ListView依旧重要,但RecyclerView确实越来越多的被大家使用.但显然并不能说RecyclerView就一定优于ListView,而是应该根据 ...
 - Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能。
		
作者:程序员小冰,CSDN博客:http://blog.csdn.net/qq_21376985 Android开发之清除缓存功能实现方法,可以集成在自己的app中,增加一个新功能. 下面是一个效果图 ...
 - Android开发——RecyclerView实现下载列表
		
本篇记录的是使用Jsoup框架爬取网页内容,结合Android的RecyclerView,从而实现批量下载小说的功能(也是我的APP星之小说下载器Android版的核心功能),思路仅供参考 本文使用了 ...
 - Android开发 静态static类与static方法持有Context是否导致内存泄露的疑问
		
简述 在Android开发的过程中,难免会使用单例模式或者静态方法工具类.我们会让它们持有一些外部的Context或者View一般有以下几种情况: 单例模式,类的全局变量持有Context 或 Vie ...
 - Android开发中Parcelable接口的使用方法
		
在网上看到很多Android初入门的童鞋都在问Parcelable接口的使用方法,小编参考了相关Android教程,看到里面介绍的序列化方法主要有两种分别是实现Serializable接口和实现Par ...
 - Android开发----RecyclerView视图的学习
		
RecyclerView RecyclerView是什么? RecyclerView是如今Android开发中最常用的控件,其相较于ListView和GridView的功能更为强大,优化了两者的各种不 ...
 - Android开发环境搭建及常见问题解决方法
		
转自: http://www.cnblogs.com/rwxwsblog/p/4769785.html 在移动互联网的时代,Android的份额早已超过了苹果.Android的出现无疑加速了移动互联网 ...
 - 【转】Android开发中让你省时省力的方法、类、接口
		
转载 http://www.toutiao.com/i6362292864885457410/?tt_from=mobile_qq&utm_campaign=client_share& ...
 - 从零开始学android开发-用Intent启动Activity的方法
		
启动另外一个Activity,可以有的方法有用setClass()和Component Name 1. 先说在setClass启动一个Activity的方法吧: Intent intent = new ...
 
随机推荐
- SQLServer 学习笔记之超详细基础SQL语句 Part 11
			
Sqlserver 学习笔记 by:授客 QQ:1033553122 -----------------------接Part 10------------------- DECLARE @myavg ...
 - XQuery使用sum求和,提示char不能转换为money解决方法
			
select axml.value('sum(/root/pro/price)','money') 以上代码提示‘char不能转换为money’的错误,发现值为'0.0E0'.改为: select a ...
 - 【Python】pydot安装失败解决方法
			
使用keras时输出网络结构需要用到pydot,总是安装失败,最后按照下面这样的步骤成功了. 1.安装graphviz:pip install graphviz 2.安装graphviz软件,地址在: ...
 - Sql Server Tempdb原理-日志机制解析实践
			
笔者曾经在面试DBA时的一句”tempdb为什么比其他数据库快?”使得95%以上的应试者都一脸茫然.Tempdb作为Sqlserver的重要特征,一直以来大家对它可能即熟悉又陌生.熟悉是我们时时刻刻都 ...
 - sql server中quotename()函数的用法(转载)
			
操作sql server尤其是写存储过程时,要用到各种各样的函数,今天就总结一个quotename()的用法.1.语法: quotename('character_string'[,'quote_ch ...
 - 反向代理负载均衡调度:nginx
			
一.概述 反向代理:以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个 ...
 - git命令:全局设置用户名邮箱配置
			
1.查看git配置信息 git config --list 2.查看git用户名 git config user.name 3.查看邮箱配置 git config user.email 4.全局配置用 ...
 - springmvc 笔记一
			
Springmvc 处理流程 所需的包 前端配置器 在web.xml中配置 <!-- 配置前端控制器 --> <servlet> <servlet-name>spr ...
 - php框架安装
			
安装yii框架 跳转到composer.phar目录 cd C:\ProgramData\ComposerSetup\bin 安装yii2高级版 php composer.phar create-pr ...
 - chrome主页被篡改为360导航之解决方式
			
昨天,安装某款游戏之后,发现chrome的主页被篡改为360导航. 进入chrome设置改动主页,又一次启动chrome还是360导航,后来发如今chrome快捷方式的属性中目标后面加了一串360导航 ...