在support-v7包中引入了很多新的m 控件,其中rccyclerview也是其中一员,它的名字来源于它的工作方式:当一个item被隐藏起来时候并没有被销毁,当建立新的item时候,组件自动复用item。但与以往经典listview不同的是,rccyclerview直接把viewholder的实现封装起来,因此用户只要实现自己的viewholder即可。
通常一个rccyclerview主要要处理以下几个部分:
layoutmanager :rccyclerview将item布局方式单独放出来供开发者选择,可以把你的item设置成水平或者垂直或者
主要有 linearlayoutmanager(线性)、gridlayoutmanager(宫格)、staggeredgridlayoutmanager(瀑布流)
adapter:适配器,在listview中也有,主要用来提供数据适配
itemanimator:负责item的动画播放修改,添加,删除或移动
itemdecoration:可以用来添加drawings或者改变item的布局,比如添加dividers
viewholder:用户实现自己的viewlder即可
点击事件:这个没有提供需要自己写,这个我在后面的例子中会给出说明
再介绍一下cardview,跟rccyclerview一样也是suooport-v7新控件,可以让我们使用类似卡片的效果,我们还可以设置卡片的圆角和阴影效果,cardview是一个layout继承自framelayout,因此需要在里面布局其他view控件,下面给出一个cardview常用属性
cardview_cardbackgroundcolor 设置背景色
cardview_cardcornerradius 设置圆角大小
cardview_cardelevation 设置z轴阴影
cardview_cardmaxelevation 设置z轴最大高度值
cardview_cardusecompatpadding 是否使用compadpadding
cardview_cardpreventcorneroverlap 是否使用preventcorneroverlap
cardview_contentpadding 内容的padding
cardview_contentpaddingleft 内容的左padding
cardview_contentpaddingtop 内容的上padding
cardview_contentpaddingright 内容的右padding
cardview_contentpaddingbottom 内容的底padding
首先在as中加入依赖
file>project structs,在+号选library dependency,加入如下来个依赖库
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI4YDOyQDM1AjM4ITMxUTMwIzLcRXZu5ibkN3Yuc2bsJmLn1Wavw1LcpDc0RHaiojIsJye.jpg)
public class item {
private string maintitle;
private string subtitle;
private boolean active;
public item(string maintitle, string subtitle, boolean active) {
this.maintitle = maintitle;
this.subtitle = subtitle;
this.active = active;
}
public item(string maintitle, string subtitle) {
public string gettitle() {
return maintitle;
public string getsubtitle() {
return subtitle;
public boolean isactive() {
return active;
}
注:isactive是为后面复杂例子准备的
item.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.cardview
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:cardbackgroundcolor="#79cdcd"
app:cardcornerradius="5dp"
app:cardelevation="5dp"
app:cardmaxelevation="8dp"
app:cardusecompatpadding="true"
app:contentpadding="10dp">
<linearlayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<textview
android:id="@+id/maintitle"
style="@style/base.textappearance.appcompat.headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:singleline="true"
android:text="title"
android:textcolor="#ffffff"
/>
android:id="@+id/subtitle"
style="@style/base.textappearance.appcompat.subhead"
android:layout_height="0dp"
android:layout_weight="1"
android:text="subtitle"
</linearlayout>
</android.support.v7.widget.cardview>
其中对cardview的背景颜色,圆角,z轴阴影做了设定,最需要注意的属性是cardusecompatpadding,它在5.0以下的系统中默认是true,但在5.0系统中默认为false,如果不设置 app:cardusecompatpadding=”true”的话会造成在5.0系统的android手机上不能看到阴影效果。
首先我们需要定义自己的viewholder类,这类必须要继承recyclerview.viewholder,内部绑定了所需要引用的数据,这里只有俩个textview
public static class viewholder extends recyclerview.viewholder {
textview maintitle;
textview subtitle;
public viewholder(view itemview) {
super(itemview);
subtitle = (textview) itemview.findviewbyid(r.id.subtitle);
maintitle = (textview) itemview.findviewbyid(r.id.maintitle);
}
然后就是我们recyleradapter()的构造器,这里我们使用集合添加item
public recyleradpater() {
super();
items = new arraylist<>();
for (int i = 0; i < item_conut; i++) {
items.add(new item("item" + i, "this is the item number" + i));
最后看下我们继承recyclerview.adapter需要重写的方法
【1】oncreateviewholder(viewgroup parent, int i) 创建视图并且返回一个匹配的viewholder
【2】onbindviewholder(viewholder holder, int position) 用每个item数据来填充viewholder
【3】getitemcount() 返回item的数目
@override
public viewholder oncreateviewholder(viewgroup viewgroup, int i) {
view v = mlayoutinflater.from(viewgroup.getcontext()).inflate(r.layout.item, viewgroup, false);
return new viewholder(v);
}
@override
public void onbindviewholder(viewholder viewholder, int position) {
item item = items.get(position);
viewholder.maintitle.settext(item.gettitle());
viewholder.subtitle.settext(item.getsubtitle());
public int getitemcount() {
return items.size();
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainactivity">
<android.support.v7.widget.recyclerview
android:id="@+id/recycler_view"
android:layout_height="match_parent">
</android.support.v7.widget.recyclerview>
</relativelayout>
2.5 在mainactivity.java中进行逻辑处理
public class mainactivity extends appcompatactivity {
private recyclerview recyclerview;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
init();
initevent();
private void init() {
recyclerview = (recyclerview) findviewbyid(r.id.recycler_view);
private void initevent() {
recyclerview.setadapter(new recyleradpater());
recyclerview.setitemanimator(new defaultitemanimator());
//recyclerview.setlayoutmanager(new linearlayoutmanager(this));//垂直线性布局
//recyclerview.setlayoutmanager(new gridlayoutmanager(this,2));//线性宫格显示,类似gridview
recyclerview.setlayoutmanager(new staggeredgridlayoutmanager(3, orientationhelper.vertical));//线性宫格显示类似瀑布流
这里由于长度都一样瀑布流跟线性宫格效果一样,可以看出有圆角阴影效果,android新控件确实视觉效果杠杠滴,material design确实多学几招,对改善ui帮助莫大!
即实现相同的recyclerview中实现不同样式的item,比如常见的headitem和bottomiitem就是通过这种方式实现的
首先事先定义出几套item的样式,这里使用了2套item样式,这里item布局仅做了颜色区分,当然可以做的更加复杂,这取决于各自的需求,这里只是演示一下多item的布局
然后利用item的isactive对item做标记
recyleradapter.java中
if (i == 0)
items.add(new item("start item " + i, "this is the start item number " + i, true));
if (i == item_conut - 1)
items.add(new item("end item " + i, "this is the end item number " + i, true));
else
items.add(new item(" item " + i, "this is the item number " + i, false));
将第一个和最后一个item单独标记处理,isactive属性标记为true
这里我们也需要重写新的方法
public int getitemviewtype(int position) {
item item = items.get(position);
return item.isactive() ? active : in_active;
其中getitemviewtype方法是用来获取当前项item(position参数)是哪种类型的布局
然后我们在viewholder中对itenm布局做选择
public viewholder oncreateviewholder(viewgroup viewgroup, int viewtype) {
final int layout = (viewtype == in_active ? r.layout.item : r.layout.item_active);
//view v = mlayoutinflater.from(viewgroup.getcontext()).inflate(r.layout.item, viewgroup, false);
view v = mlayoutinflater.from(viewgroup.getcontext()).inflate(layout, viewgroup, false);
return new viewholder(v);
运行一下,这里只是实现了非常简单的多item布局
recylerview点击事件需要我们自己写这点就比较麻烦
这里我们在适配器中通过接口方式来写自己的itemlistener
recyleradapter.java
定义抽象接口
public interface onitemclicklisterner {
void onitemclick(view view, int position);
void onitemlongclick(view view, int position);
public void setonitemclicklitener(onitemclicklisterner monitemclicklisterner) {
this.monitemclicklisterner = monitemclicklisterner;
然后在onbindviewholder中处理监听事件的方法
//如果设置了回调则设施点击事件
if (monitemclicklisterner != null) {
viewholder.itemview.setonclicklistener(new view.onclicklistener() {
@override
public void onclick(view v) {
int pos = viewholder.getlayoutposition();
monitemclicklisterner.onitemclick(viewholder.itemview, pos);
}
});
viewholder.itemview.setonlongclicklistener(new view.onlongclicklistener() {
public boolean onlongclick(view v) {
monitemclicklisterner.onitemlongclick(viewholder.itemview, pos);
return false;
最后处理集中到mainactivity中来具体处理使用
mrecyleradpater.setonitemclicklitener(new recyleradpater.onitemclicklisterner() {
@override
public void onitemclick(view view, int position) {
toast.maketext(mainactivity.this, "click item" + position, toast.length_short).show();
}
public void onitemlongclick(view view, int position) {
mrecyleradpater.removedata(position);
toast.maketext(mainactivity.this, "long click delete item" + position, toast.length_short).show();
});
为了更新view,在listview中我们只有一个方法来监听数据item变化notifydatasetchanged(),而在recylerview的adapter中,有多个方法
notifyitemchanged(int position) : position数据发生了改变,那调用这个方法,就会回调对应position的onbindviewholder()方法了
notifyiteminserted(int position):这个方法是在第position位置被插入了一条数据的时候可以使用这个方法刷新,注意这个方法调用后会有插入的动画,这个动画可以使用默 认的,也可以自己定义。
notifyitemremoved(int position):删除position位置上的item
notifyitemmoved(int fromposition, int toposition):这个方法是从fromposition移动到toposition为止的时候可以使用这个方法刷新
notifyitemrangechanged(int positionstart, int itemcount):刷新从positionstart开始itemcount数量的item了(这里的刷新指回调onbindviewholder()方法)
notifyitemrangeinserted(int positionstart, int itemcount):批量插入
notifyitemrangeremoved(int positionstart, int itemcount):第position个被删除的时候刷新,同样会有动画
notifydatasetchanged()改变数据视图
我们在adapter中加入增删函数
/*添加*/
public void additem(int pos) {
items.add(new item("new item", "this is the new item ", false));
notifyiteminserted(pos);
/*删除*/
public void removedata(int pos) {
items.remove(pos);
notifyitemremoved(pos);
然后在mainactivity中调用即可。
长按删除item
点击弹出toast提示,长按删除item,点击menu加号添加item
转载:http://blog.csdn.net/xsf50717/article/details/50086615