1、概述

在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

2、实现一个基本的RecyclerView(结合cardview)

首先在AS中加入依赖

File>project structs,在+号选Library Dependency,加入如下来个依赖库

2.1 首先定义item的bean,主要包括一个主标题和副标题

Item.java

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) {
        this.maintitle = maintitle;
        this.subtitle = subtitle;

    }

    public String getTitle() {
        return maintitle;
    }

    public String getSubtitle() {
        return subtitle;
    }

    public boolean isActive() {
        return active;
    }
}

注:isActive是为后面复杂例子准备的

2.2  设置item对应的布局文件

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"
            />

        <TextView
            android:id="@+id/subtitle"
            style="@style/Base.TextAppearance.AppCompat.Subhead"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"
            android:singleLine="true"
            android:text="Subtitle"
            android:textColor="#FFFFFF"
            />

    </LinearLayout>
</android.support.v7.widget.CardView>

其中对cardview的背景颜色,圆角,z轴阴影做了设定,最需要注意的属性是cardUseCompatPadding,它在5.0以下的系统中默认是true,但在5.0系统中默认为false,如果不设置 app:cardUseCompatPadding=”true”的话会造成在5.0系统的Android手机上不能看到阴影效果。

2.3 适配器recylerAdapter.java

首先我们需要定义自己的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());

    }

    @Override
    public int getItemCount() {
        return items.size();
    }

2.4 主布局文件activity_main.xml,只有一个recylerView控件

<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_width="match_parent"
        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帮助莫大!

3、实现多Item布局

即实现相同的RecyclerView中实现不同样式的item,比如常见的headitem和bottomiItem就是通过这种方式实现的

首先事先定义出几套item的样式,这里使用了2套item样式,这里item布局仅做了颜色区分,当然可以做的更加复杂,这取决于各自的需求,这里只是演示一下多item的布局

然后利用item的isActive对item做标记

recylerAdapter.java中

public RecylerAdpater() {
        super();
        items = new ArrayList<>();
        for (int i = 0; i < ITEM_CONUT; i++) {
            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

这里我们也需要重写新的方法

@Override
    public int getItemViewType(int position) {
        Item item = items.get(position);
        return item.isActive() ? ACTIVE : IN_ACTIVE;
    }

其中getItemViewType方法是用来获取当前项Item(position参数)是哪种类型的布局

然后我们在viewholder中对itenm布局做选择

@Override
    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布局

4、实现一个带点击相应的瀑布流

4.1 监听事件处理

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() {
                @Override
                public boolean onLongClick(View v) {
                    int pos = viewHolder.getLayoutPosition();
                    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();
            }

            @Override
            public void onItemLongClick(View view, int position) {
                mRecylerAdpater.removeData(position);
                Toast.makeText(MainActivity.this, "long click delete item" + position, Toast.LENGTH_SHORT).show();
            }
        });

4.2 改变item集合(添加删除)

为了更新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

所有demo地址http://download.csdn.net/detail/xsf50717/9314043

RecyclerView+Cardview学习探索的更多相关文章

  1. RecyclerView,CardView导入和使用(Demo)

    简介: 这篇文章是ANDROID L——Material Design详解(UI控件)的一个补充或者说是应用实例,如果有时间建议大家稍微浏览一下上篇文章. 本文主要介绍Android L新增加的两个U ...

  2. RecyclerView+CardView简单使用

    RecyclerView取代Listview用来显示数据,除此之外还能实现瀑布流的布局.CardView让我们的界面更好看,此外还将使用官方的下拉刷新. 添加支持: compile 'com.andr ...

  3. Material design之New Widgets(RecyclerView CardView)

    New Widgets:提供了两个新的控件 RecyclerView CardView 这两个控件包含在了Android L的support library中, 他们可以用于显示复杂的布局而且都默认采 ...

  4. ANDROID L——RecyclerView,CardView进口和使用(Demo)

    转载请注明本文出自大苞米的博客(http://blog.csdn.net/a396901990),谢谢支持! 简单介绍: 这篇文章是ANDROID L--Material Design具体解释(UI控 ...

  5. App自动化测试框架学习探索--从零开始设计

    App自动化测试框架学习探索--从零开始设计---持续更新中,敬请关注 1 批量执行app自动化测试使用多线程设计思路: 1)并发级别选择用methods 2)采用@Test多线程,数据提供类dp单线 ...

  6. 利用RecyclerView CardView实现新闻卡片样式

    引入的包: demo结构: 测试代码: News.java: package com.zzw.testcardview; import java.io.Serializable; public cla ...

  7. Android学习探索之Java 8 在Android 开发中的应用

    前言: Java 8推出已经将近2年多了,引入很多革命性变化,加入了函数式编程的特征,使基于行为的编程成为可能,同时减化了各种设计模式的实现方式,是Java有史以来最重要的更新.但是Android上, ...

  8. Android学习探索之本地原生渲染 LaTeX数据公式

    前言: 一直致力于为公司寻找更加高效的解决方案,作为一款K12在线教育App,功能中难免会有LaTeX数学公式的显示需求,这部分公司已经实现了此功能,只是个人觉得在体验和效率上还是不太好,今天来聊一下 ...

  9. Android学习探索之运用MVP设计模式实现项目解耦

    前言: 一直致力于提高开发效率降低项目耦合,今天想抽空学习一下MVP架构设计模式,学习一下如何运用到项目中. MVP架构设计模式 MVP模式是一种架构设计模式,也是一种经典的界面模式.MVP中的M代表 ...

随机推荐

  1. Android安全升级的7.0: Nougat

    Tamic http://www.jianshu.com/users/3bbb1ddf4fd5/latest_articles 今年夏天以来,Google做了多种增强的安全性在Android的7.0N ...

  2. ROS机器人程序设计(原书第2版)补充资料 (捌) 第八章 导航功能包集入门 navigation

    ROS机器人程序设计(原书第2版)补充资料 (捌) 第八章 导航功能包集入门 navigation 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中 ...

  3. Dynamics CRM FORM脚本库加载本地脚本

    用传统的开发方式,js脚本都是保存在数据库中的,这样也方便迁移,但如果不想存数据库而是存在物理磁盘上,则可通过下述代码,将脚本存放在CRMWEB文件夹的某个路径下,每次都动态引用本地JS. funct ...

  4. 使用反射创建Bean、Spring中是如何根据类名配置创建Bean实例、Java提供了Class类获取类别的字段和方法,包括构造方法

    Java提供了Class类,可以通过编程方式获取类别的字段和方法,包括构造方法    获取Class类实例的方法:   类名.class   实例名.getClass()   Class.forNam ...

  5. Swift中类似C++和ruby中的final机制

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道在C++和ruby语言的错误处理中有一种final机制 ...

  6. ROS讲座 关于ROS2和Gazebo C++ in Open Source Robotics

    分享一个不错的介绍ROS2和Gazebo的视频讲座. Gazebo中的云彩飘动起来了!!!! 超清视频分享网址:    http://v.youku.com/v_show/id_XMTcyMzY0Nz ...

  7. Android软件设置自动检查更新

    如果让我推荐功能强大的第三方集成开发包,我一定会推荐友盟,有着强大的软件统计,分析功能(原谅我,我不是打广告). 这一篇介绍友盟的自动更新功能,但是首先你得拥有友盟. 友盟的集成步骤 1.1 导入SD ...

  8. HTML5中 HTML表单和PHP环境搭建及与PHP交互 韩俊强的博客

    每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 知识点概括:HTML表单/PHP环境搭建/表单提交数据与PHP交互 第一部分:HTML表单 <!DOCTYP ...

  9. 带吸附效果的ViewPager(一)

    什么叫吸附效果?先看一个示例更为直观,借用网上的一个效果图: 类似这种效果的app很多,网上的实现方法也是很多,但各种重写各种监听又令人不胜其烦,今日突发奇想,顺着自己的思路实现了类似的效果,不敢独享 ...

  10. Android异常:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original

    Android异常:android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that cr ...