天天看点

RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流

在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,加入如下来个依赖库

RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流

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+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流
RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流

即实现相同的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布局

RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流
RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流

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

RecyclerView+Cardview学习探索1、概述 2、实现一个基本的RecyclerView(结合cardview) 3、实现多Item布局 4、实现一个带点击相应的瀑布流

转载:http://blog.csdn.net/xsf50717/article/details/50086615

继续阅读