Android开发学习之路-RecyclerView使用初探
在进行一些MaterialDesign规范开发的时候,比如之前说到的CoordinateLayout实现的向上折叠效果的时候,如果依然使用ListView,那么这种效果是做不出来的,因为ListView不兼容这个控件,而替代它的就是RecyclerView。
和ListView的区别:
①RecyclerView只关心item的重用和缓存
②RecyclerView不关心item的分隔风格(交给ItemDecoration)
③RecyclerView不关心item的动画(交给ItemAnimator)
④RecyclerView不关心item的布局(交给LayoutManager)
本文为初探,所以先不详解②③④这几个内容,先记录一下用法和遇到的坑,后续有时间再更新!
先放一下效果图,动画效果在之前的博客也有提到,可以参考,主要的是中间的RecyclerView,这里主要讲如何使用它以及遇到的一些问题

先添加依赖,版本无所谓:
compile 'com.android.support:recyclerview-v7:23.1.1'
布局文件如下,注意最后一个属性可以不用理,这是用来协调动画效果的(就是把上面图片推上去的效果)
<android.support.v7.widget.RecyclerView
android:id="@+id/main_lv"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
自定义一个Adapter继承自RecyclerView.Adapter,代码如下:
public class MyAdapter extends RecyclerView.Adapter {
private static final String TAG = "MyAdapter";
private final List<Map<String, Object>> data;
private final View root;
private OnItemButtonCLickListener listener;
public MyAdapter(List<Map<String, Object>> data, View root) {
this.data = data;
this.root = root;
}
public void setOnItemButtonClickListener(OnItemButtonCLickListener listener){
this.listener = listener;
}
class ViewHolder extends RecyclerView.ViewHolder {
TextView reason, money, date;
Button delete,alter;
public ViewHolder(View itemView) {
super(itemView);
reason = (TextView) itemView.findViewById(R.id.main_rv_item_reason);
money = (TextView) itemView.findViewById(R.id.main_rv_item_money);
date = (TextView) itemView.findViewById(R.id.main_rv_item_date);
delete = (Button) itemView.findViewById(R.id.main_rv_item_remove);
alter = (Button) itemView.findViewById(R.id.main_rv_item_alter);
}
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
ViewHolder vh = new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout
.main_lv_item, null));
return vh;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final ViewHolder vh = (ViewHolder) holder;
vh.date.setText(data.get(position).get("date").toString());
vh.reason.setText(data.get(position).get("reason").toString());
vh.money.setText(data.get(position).get("money").toString());
vh.delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Snackbar snackBar = Snackbar.make(root, "Are you sure to delete it?", Snackbar.LENGTH_LONG);
snackBar.setAction("YES", new MyOnClickListener(vh.getLayoutPosition()));
snackBar.show();
}
});
vh.alter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
listener.OnItemAlter(vh.getLayoutPosition());
}
});
}
@Override
public int getItemCount() {
return data.size();
}
private class MyOnClickListener implements View.OnClickListener {
private final int position;
public MyOnClickListener(int position) {
this.position = position;
}
@Override
public void onClick(View v) {
listener.OnItemDelete(position);
}
}
interface OnItemButtonCLickListener {
void OnItemAlter(int position);
void OnItemDelete(int position);
}
}
解析:构造方法中获取到数据源以及根View,根View用来显示SnackBar,如果不知道SnackBar,请看上一篇。然后创建一个内部类,继承自RecyclerView.ViewHolder,用它来保存每一个Item的全部控件。接下来重写几个方法:getItemCount、onBindViewHolder以及onCreateViewHolder,他们分别是返回item个数,绑定ViewHolder以及创建ViewHolder,创建ViewHolder就是通过Item的布局文件获取每个控件的实例,绑定ViewHolder就是把数据源中的数据映射到Item的控件中,因为我们的Item中还有删除和修改按钮,所以我们为它们添加点击事件也是在onBindViewHolder中进行。接下来我们定义一个接口OnItemButtonClickListener并且定义两个方法分别用来回调点击删除和修改,并创建接口的对象,在按钮点击的时候分别调用接口的两个方法,并传入点击的item的position。
Activity部分代码如下:
rv = (RecyclerView) findViewById(R.id.main_lv);
adapter = new MyAdapter(data, root);
rv.setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false)); // 设置布局,否则无法正常使用
adapter.setOnItemButtonClickListener(this);
rv.setAdapter(adapter);
@Override
public void OnItemAlter(int position) {
//Intent intent = new Intent(MainActivity.this, AlterActivity.class);
//intent.putExtra("id", Integer.parseInt(data.get(position).get("id").toString()));
//intent.putExtra("date", data.get(position).get("date").toString());
//intent.putExtra("money", data.get(position).get("money").toString());
//intent.putExtra("reason", data.get(position).get("reason").toString());
//startActivityForResult(intent, REQUEST_ALTER);
} @Override
public void OnItemDelete(int position) {
Log.d(TAG, "OnItemDelete() called with: " + "position = [" + position + "]");
//Map<String, Object> backup = data.get(position);
//data.remove(position);
//database.execSQL("delete from tally where id=?", new String[]{backup.get
// ("id").toString()});
adapter.notifyItemRemoved(position);
}
解析:获取RecyclerView的实例之后,设置对应的布局管理器,然后通过setOnItemButtonClickListener设置回调函数并实现,最后给RecyclerView设置adapter即可。
遇到的问题:
①刚开始忘记设置布局,RecyclerView不显示出来
②因为我们在删除item之后调用了notifyItemRemoved方法来显示动画并刷新,在onBindViewHolder中,对删除按钮监听之后调用接口方法的时候传入了position,这个position是错误的,因为在绑定的时候固定了,如果数据源的数据被删除了,数据源的size会变小,这个position就不再对应于数据源的每一个项就会产生混乱,所以这里应该传入viewholder.getLayoutPosition()所得到的值,这个值是对应点击而产生的。
③如果在RecyclerView的第一项前面插入一个item,并且调用notifyItmeInserted(0),是不会播放动画效果的
Android开发学习之路-RecyclerView使用初探的更多相关文章
- Android开发学习之路-RecyclerView滑动删除和拖动排序
Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...
- Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析
这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...
- Android开发学习之路--Android系统架构初探
环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...
- Android开发学习之路--基于vitamio的视频播放器(二)
终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...
- Android开发学习之路--Android Studio cmake编译ffmpeg
最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...
- Android开发学习之路--网络编程之xml、json
一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...
- Android开发学习之路--Activity之初体验
环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...
- Android开发学习之路--MAC下Android Studio开发环境搭建
自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...
- Android开发学习之路-记一次CSDN公开课
今天的CSDN公开课Android事件处理重难点快速掌握中老师讲到一个概念我觉得不正确. 原话是这样的:点击事件可以通过事件监听和回调两种方法实现. 我一听到之后我的表情是这样的: 这跟我学的看的都不 ...
随机推荐
- ExecutorService中submit()和execute()的区别
在使用java.util.concurrent下关于线程池一些类的时候,相信很多人和我一样,总是分不清submit()和execute()的区别,今天从源码方面分析总结一下. 通常,我们通过Execu ...
- c语言结构体
[C语言]21-结构体 本文目录 一.什么是结构体 二.结构体的定义 三.结构体变量的定义 四.结构体的注意点 五.结构体的初始化 六.结构体的使用 七.结构体数组 八.结构体作为函数参数 九.指向结 ...
- python学习 1基础
对象的等于只是对于值而言 函数定义没有变量提升 常用对象 list []: 列表, 排序省空间 tuple (): 元组,一旦初始化不可修改 dict {}: 字典,方便查询 set {}:集合, 值 ...
- java.lang.OutOfMemoryError: PermGen space错误解决方法
1. MyEclipse 中报 PermGen space window--> preferences-->Myclipse-->Servers-->Tomcat- ...
- iOS APP性能优化
:应用启动时间 应用启动时,只加载启动相关的资源和必须在启动时加载的资源. :本地图片加载方式 本地图片加载常用方法有两种: a. [UIImage imageNamed:@"xx.png& ...
- JNI使用问题记录
此文章包含Android JNI学习过程中的遇到的各种错误记录和学习总结. 1.错误:java.lang.UnsatisfiedLinkError: Native method not found: ...
- [LintCode] Trapping Rain Water 收集雨水
Given n non-negative integers representing an elevation map where the width of each bar is 1, comput ...
- Dexpress 中 grid的使用
grid 中加入checkbox Run desiger Columns ColumnEdit中选择checkbox 此时我们要在后台手动指定一个数据列如下代码: dtRebatesReport.Co ...
- c/c++头文件_string
string, cstring, string.h 一.string头文件 主要包含一些字符串转换的函数 // sto* NARROW CONVERSIONS// sto* WIDE CONVERSI ...
- VB6.0 为批量字体改名
从网上下载了一个字符包,解压以后查看,发现文件名是这种形式:0120_XXXXXX_GBK.ttf,看上去很不雅观.我想改成 XXXXXX简体.ttf 这种形式,但字体有300多个,手动修改太浪费时间 ...