Android RecyclerView点击事件
一、概述
随着android l版本的发布,recyclerview已经逐渐地取代了listview,用来显示较多的数据集,recyclerview相比listview在性能上有了大幅度的提升,可以说recyclerview是abslistview的升级版本。recyclerview自带了viewholder使用,与listview缓存convertview不同的是,recyclerview缓存的是viewholder,操作对象也是viewholder。虽然listview也带有缓存convertview的功能,但是当使用listview时,显示、缓存、回收、布局等都是耦合在一起的;而recyclerview对其进行了解耦,操作更灵活,使得开发者可以更好的自定义各种各样的效果,另外recyclerview假如了局部刷新。关系如下图所示:
二、基本使用
recyclerview提供了下面几种角色
1.recyclerview.adapter 适配器
2.recyclerview.layoutmanager 布局器,用于管理布局显示,官方提供以下几种方式
linearlayoutmanager 显示垂直或水平滚动的列表项
gridlayoutmanager 以网格方式显示
staggeredgridlayoutmanager 以交错网格显示
同时,开发者也可以自定义layoutmanager,继承recyclerview.layoutmanager。
3.recycler.itemdecoration 每个item附加的子视图,可用来绘制divider,设置padding等
4.recyclerview.itemanimator 负责添加、删除数据时的动画效果
具体的使用方法见 官方文档
项目中使用
activity中
protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); initview(); } private void initview() { recyclerview = (recyclerview) findviewbyid(r.id.rv); // use this setting to improve performance if you know that changes // in content do not change the layout size of the recyclerview recyclerview.sethasfixedsize(true); // use a linear layout manager linearlayoutmanager ll = new linearlayoutmanager(this); recyclerview.setlayoutmanager(ll); initializedata(); recycleradapter = new recycleradapter(persons); recyclerview.setadapter(recycleradapter); } private void initializedata(){ persons = new arraylist<>(); persons.add(new person("emma wilson", "23 years old", r.mipmap.ic_launcher)); persons.add(new person("lavery maiss", "25 years old", r.mipmap.ic_launcher)); persons.add(new person("lillie watts", "35 years old", r.mipmap.ic_launcher)); }
自定义adapter
public class recycleradapter extends recyclerview.adapter<recycleradapter.viewholder>{ private list<person> list; public recycleradapter(list<person> list) { this.list = list; } //为viewholder设置数据 @override public viewholder oncreateviewholder(viewgroup parent, int viewtype) { view view = layoutinflater.from(parent.getcontext()).inflate(r.layout.item, parent, false); viewholder viewholder = new viewholder(view); return viewholder; } @override public void onattachedtorecyclerview(recyclerview recyclerview) { super.onattachedtorecyclerview(recyclerview); } //用于创建viewholder @override public void onbindviewholder(viewholder holder, int position) { person person = list.get(position); holder.nametv.settext(person.name); holder.agetv.settext(person.age); holder.imageview.setimageresource(person.photoid); } @override public int getitemcount() { return list.size(); } // 删除指定的item public void removedata(int position) { list.remove(position); // 通知recyclerview控件某个item已经被删除 notifyitemremoved(position); } // 在指定位置添加一个新的item public void additem(person person,int positiontoadd) { list.add(person); // 通知recyclerview控件插入了某个item notifyiteminserted(positiontoadd); } public class viewholder extends recyclerview.viewholder { textview nametv; textview agetv; imageview imageview; public viewholder(view itemview) { super(itemview); nametv = (textview) itemview.findviewbyid(r.id.name); agetv = (textview) itemview.findviewbyid(r.id.age); imageview = (imageview) itemview.findviewbyid(r.id.avater); } } }
item动画如有需要可以自己手动添加,这个不是今天的重点,这里附上两个不错的开源项目 这里 和 这里
recyclerview的点击事件
官方文档中并没有给我们类似listview的onitemclicklistener回调方法,由于recyclerview比listview更高级,所以它并没有行或者列的概念,子view可以任意布局,每个子view处理自己的onclick事件,也就是说在adapter中给子view的rootview设置点击回调。
我们今天所要实现的是另外一种方式,类似listview的onitemclicklistener的方式。通过文档我们知道recyclerview留给开发者一个recyclerview.onitemtouchlistener接口,我们要做的就是实现它,实现点击的回调和长按回调。当然了,这种方式只是一个开始,我们还可以拓展为各种复杂的手势操作的回调
public class recycleritemclicklistener implements recyclerview.onitemtouchlistener{ private view childview; private recyclerview touchview; public recycleritemclicklistener(context context, final onitemclicklistener mlistener) { mgesturedetector = new gesturedetector(context, new gesturedetector.simpleongesturelistener(){ @override public boolean onsingletapup(motionevent ev) { if (childview != null && mlistener != null) { mlistener.onitemclick(childview, touchview.getchildposition(childview)); } return true; } @override public void onlongpress(motionevent ev) { if (childview != null && mlistener != null) { mlistener.onlongclick(childview, touchview.getchildposition(childview)); } } }); } gesturedetector mgesturedetector; public interface onitemclicklistener { public void onitemclick(view view, int position); public void onlongclick(view view, int posotion); } @override public boolean onintercepttouchevent(recyclerview recyclerview, motionevent motionevent) { mgesturedetector.ontouchevent(motionevent); childview = recyclerview.findchildviewunder(motionevent.getx(), motionevent.gety()); touchview = recyclerview; return false; } @override public void ontouchevent(recyclerview recyclerview, motionevent motionevent) { } }
我们在onintercepttouchevent的方法中注册了手势操作,当有特定的手势的时候我们就可以通过simplegesturelistener回调接口接收到,其中我们实现了 点击和长按,然后回调我们自己定义的接口。使用也很简单
recyclerview.addonitemtouchlistener(new recycleritemclicklistener(this, new recycleritemclicklistener.onitemclicklistener() { @override public void onitemclick(view view, int position) { log.d(tag, "onitemclick : postion " + position); } @override public void onlongclick(view view, int posotion) { log.d(tag, "onlongclick position : " + posotion); } }));
对于手势操作我们可以定义更多用于对itemview的操作回调。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读