在进行一些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. 在Heroku上部署Node.js应用

    最近在学习Node.js,想找一个可以免费部署Node的平台,于是便找到了Heroku 直接进入主题,接下来我们一步一步部署自己的Node应用. 步骤1: 注册一个免费的Heroku账号. 步骤2: ...

  2. WEB开发入门

    对服务器的概念需要更新一下: 从物理上来说,服务器就是一台PC机,至少8核,以T计算,带宽100M以上 一般有的服务器 1. web服务器 -- PC机上安装一个具有web服务的软件 2. 数据库服务 ...

  3. 小tips

    ios::sync_with_stdio(false);  加速读入的,加上这条语句可以使cin和cout的速度和scanf和printf差不多.

  4. DelphiXE10.1获取Administrator所有权的方法

    操作: 菜单选择Proceject->Options->Application->把Enable Admonistrator Privileges打勾(manifest file - ...

  5. [bzoj4726]Sabota

    做的题太少,什么都要看题解.. 题意只给出一个叛徒,则他一定是叶子结点(最坏情况下),那么"带头反叛"的点一定构成了一条链. 令f[u]表示u不带头反叛的最小值,则考虑它的每一支儿 ...

  6. Python 基础语法学习笔记

    以下运行结果均通过Python3.5版本实测! 1.列表转换为字典 a = ['a', 'b'] b = [1, 2] c = ['c','d'] print (dict([a,b,c])) 输出结果 ...

  7. 2.1 -1.0 Xcode(发布时间、使用、快捷键、插件相关)

    本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 1.0 Xcode 发布时间 版本 iOS 版本 手机 日期 特殊介绍 Xcode 3.1 ...

  8. Python学习笔记(1)

    从今天开始正式学习python,教程看的是廖雪峰老师的Python 2.7教程.链接在此:http://www.liaoxuefeng.com/wiki/0014316089557264a6b3489 ...

  9. PLSQL配置新的oracle实例

    在Win环境下的Oracle中,D:\Oracle\product\10.1.0\db_1\NETWORK\ADMIN\tnsnames.ora文件很重要,它作用是:本地命名的配置.本地名可以用简单的 ...

  10. tornado 学习笔记16 HTTP1Connection

    HTTP/1.x协议的具体实现.实现HTTPConnection接口. 16.1 构造函数 定义: def __init__(self, stream, is_client, params=None, ...