在进行一些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使用初探的更多相关文章

  1. Android开发学习之路-RecyclerView滑动删除和拖动排序

    Android开发学习之路-RecyclerView使用初探 Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析 Android开 ...

  2. Android开发学习之路-RecyclerView的Item自定义动画及DefaultItemAnimator源码分析

    这是关于RecyclerView的第二篇,说的是如何自定义Item动画,但是请注意,本文不包含动画的具体实现方法,只是告诉大家如何去自定义动画,如何去参考源代码. 我们知道,RecyclerView默 ...

  3. Android开发学习之路--Android系统架构初探

    环境搭建好了,最简单的app也运行过了,那么app到底是怎么运行在手机上的,手机又到底怎么能运行这些应用,一堆的电子元器件最后可以运行这么美妙的界面,在此还是需要好好研究研究.这里从芯片及硬件模块-& ...

  4. Android开发学习之路--基于vitamio的视频播放器(二)

      终于把该忙的事情都忙得差不多了,接下来又可以开始good good study,day day up了.在Android开发学习之路–基于vitamio的视频播放器(一)中,主要讲了播放器的界面的 ...

  5. Android开发学习之路--Android Studio cmake编译ffmpeg

      最新的android studio2.2引入了cmake可以很好地实现ndk的编写.这里使用最新的方式,对于以前的android下的ndk编译什么的可以参考之前的文章:Android开发学习之路– ...

  6. Android开发学习之路--网络编程之xml、json

    一般网络数据通过http来get,post,那么其中的数据不可能杂乱无章,比如我要post一段数据,肯定是要有一定的格式,协议的.常用的就是xml和json了.在此先要搭建个简单的服务器吧,首先呢下载 ...

  7. Android开发学习之路--Activity之初体验

    环境也搭建好了,android系统也基本了解了,那么接下来就可以开始学习android开发了,相信这么学下去肯定可以把android开发学习好的,再加上时而再温故下linux下的知识,看看androi ...

  8. Android开发学习之路--MAC下Android Studio开发环境搭建

    自从毕业开始到现在还没有系统地学习android应用的开发,之前一直都是做些底层的驱动,以及linux上的c开发.虽然写过几个简单的app,也对android4.0.3的源代码做过部分的分析,也算入门 ...

  9. Android开发学习之路-记一次CSDN公开课

    今天的CSDN公开课Android事件处理重难点快速掌握中老师讲到一个概念我觉得不正确. 原话是这样的:点击事件可以通过事件监听和回调两种方法实现. 我一听到之后我的表情是这样的: 这跟我学的看的都不 ...

随机推荐

  1. 安装openssl 扩展的时候出现Cannot find config.m4. Make sure that you run '/usr/local/php/bin/phpize' in the top level source directory of the module的解决方法

    进入php源码包目录:cd /usr/local/php-5.6.25/ext/openssl 执行命令:  cp ./config0.m4 ./config.m4 即可

  2. Unity.Interception(AOP)

            在前面我们学习到的是Unity依赖注入(DI)与统一容器来松散耦合,这个设计已经对我们系统带来了很多的好处.但是我们还会想尝试和遵循单一职责,开放封闭原则.比如我们不应该在我们的Bus ...

  3. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  4. HDU5509 : Pattern String

    只要求出两个字符串的最小表示,然后就可以判断是否循环同构. 枚举最小表示的开头在哪个位置,然后求出Hash值,如果两个串的Hash值集合有交,那么说明循环同构. 因为串经过压缩,原串的长度很大,不能直 ...

  5. Shell特殊变量:Shell $0, $#, $*, $@, $?, $$和命令行参数

    特殊变量列表 变量 含义 $0 当前脚本的文件名 $n 传递给脚本或函数的参数.n 是一个数字,表示第几个参数.例如,第一个参数是$1,第二个参数是$2. $# 传递给脚本或函数的参数个数. $* 传 ...

  6. Easyui之datagrid实现点击单元格修改单元格背景颜色

    前段时间有个需求中有点击datagrid的单元格实现某种事件,调用datagrid的onclickCell这个方法很容易实现,但是体验不好啊,完全不知道自己刚才点击的是哪个单元格,然后就尝试单击单元格 ...

  7. HDU 5976 数学,逆元

    1.HDU 5976 Detachment 2.题意:给一个正整数x,把x拆分成多个正整数的和,这些数不能有重复,要使这些数的积尽可能的大,输出积. 3.总结:首先我们要把数拆得尽可能小,这样积才会更 ...

  8. C#判断数组是否为空

    string[] array=new[] { "1", "2", "3", "4", "5" }; ...

  9. php 中的 基本区别点

    this.self.parent https://my.oschina.net/jackguo/blog/189020

  10. “我爱背单词”beta版发布与使用说明

    我爱背单词BETA版本发布 第二轮迭代终于画上圆满句号,我们的“我爱背单词”beta版本已经发布. Beta版本说明 项目名称 我爱背单词 版本 Beta版 团队名称 北京航空航天大学计算机学院  拒 ...