RecyclerView+CardView使用解析

导读:

RecyclerView:

RecyclerView 比 ListView 更高级且更具灵活性。 它是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效的滚动操作。 如果您有数据集合,其中的元素将因用户操作或网络事件而在运行时发生改变,请使用 RecyclerView 。

RecyclerView只管回收与复用View,其他的你可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由,可以轻松的通过这个控件实现ListView,GirdView,瀑布流等效果.

CradView:顾名思义就是卡片view,可以设置阴影,圆角,等等。。

---------本文有借鉴薛瑄大神的文章,大神就是大神写的是真的好

适合人群:这是一篇适合新手使用RecyclerView控件的解析。

准备工作:


实际上第一条导包好像是把所有的support:design包里面的东西都引入了,因为这个时候实现Toolbar不需要额外导包。

实现RecyclerView:

1.想要控制其item们的排列方式,请使用布局管理器LayoutManager


2.如果要创建一个适配器,请使用RecyclerView.Adapter

3.想要控制Item间的间隔,请使用RecyclerView.ItemDecoration

4.想要控制Item增删的动画,请使用RecyclerView.ItemAnimator
在DefaultItemAnimator中有Add、Remove、Move、Change四种动画.
要实现这四种动画,数据更新时要使用以下方法
Adapter.notifyItemInserted(int position) 

Adapter.notifyItemRemoved(int position)

Adapter.notifyItemChanged(int position)

Adapter.notifyItemMoved(int fromPosition, int  toPosition)

5.CardView 扩展 FrameLayout 类并让您能够显示卡片内的信息,这些信息在整个平台中拥有一致的呈现方式。CardView 小部件可拥有阴影和圆角。

其中1,2是必须实现的,3,4,5可以让RecyclerView变得更加美观。

RecyclerView-----xml布局:

?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/liner"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/btn_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="添加"
            android:textAllCaps="false" />
        <Button
            android:id="@+id/btn_delete"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="删除"
            android:textAllCaps="false" />
        <Button
            android:id="@+id/btn_list"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="List"
            android:textAllCaps="false" />
        <Button
            android:id="@+id/btn_grid"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="Grid"
            android:textAllCaps="false" />
        <Button
            android:id="@+id/btn_flow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="flow"
            android:textAllCaps="false" />
    </LinearLayout>


    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>

实现MyRecyclerViewAdapter 

class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> {
    LayoutInflater mInflater;
  //  Context context;
    private List<Mtext> datas;

    public MyRecyclerViewAdapter(Context context,List<Mtext> datas){
         mInflater = LayoutInflater.from(context);
        this.datas=datas;
       // this.context=context;
      }



/*①onCreateViewHolder()
    这个方法主要生成为每个Item inflater出一个View,
    但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,
    然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写*/
//onCreateViewHolder 通过这个方法来创建ViewHolder,把自定义的viewholder创建出来
//实际上就是创建条目的View的结构
    @Override
    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
           //View.inflate将布局给找到
        View view=View.inflate(parent.getContext(),R.layout.item_recyclerview,null);
        //该方法返回一个ViewHolder,参数是view
        return new MyViewHolder(view);
    }
/*
* ②onBindViewHolder()
     这个方法主要用于适配渲染数据到View中。方法提供给你了一个viewHolder
     这里面主要进行数据整理并显示在界面上,我怎么觉得我打字是这么的快,哈哈! 皮
     */
//通过onBindViewHolder将点击事件传到界面上进行操作
    @Override
    public void onBindViewHolder(MyViewHolder holder, final int position) {
               String data=datas.get(position).getUsertext();
               holder.tv_title.setText(data);        
  holder.itemView.setOnClickListener(new View.OnClickListener() {
               @Override
               public void onClick(View view) {   //单击事件
                   if (listener!=null){
                       listener.onClick(datas.get(position).getUsertext(),datas.get(position).getPostion());
                   }
               }
           });
        holder.itemView.setOnLongClickListener(new View.OnLongClickListener() {  //长按事件
            @Override
            public boolean onLongClick(View view) {
                if(listener!=null){
                    listener.onLongClick(datas.get(position).getUsertext(),datas.get(position).getPostion());
                }
                return true;
            }
        });
    }
    //添加数据
    public void addData( String username,int position) {
         Mtext mtext=new Mtext(username,position);
         datas.add(mtext);
        //刷新适配器
        notifyItemInserted(position);
    }
    //移除数据
    public void removeData(int position) {
        datas.remove(position);
        //刷新适配器
        notifyItemRemoved(position);
    }
    /*总共有多少个条目*/
    @Override
    public int getItemCount() {
        return datas==null? 0:datas.size();
    }
   //一个最基本的RecyclerView适配器需要具备这几个方法
     class MyViewHolder extends RecyclerView.ViewHolder{
       private TextView tv_title;
        public MyViewHolder(View itemView) {
            super(itemView);
            //itemView 实际上就是条目的View对象  在条目的View对象中找到要修改的控件 通过
            //成员变量缓存起来
            tv_title=itemView.findViewById(R.id.tv_title);
        }
    }
    //声明一个点击事件接口类型的成员变量
    private MyClickListener listener;

    //传入点击事件具体实现的方法
    public void setListener(MyClickListener listener) {
        this.listener = listener;
    }

    //声明一个点击事件的接口
    public interface MyClickListener{
        void onClick(String username,int postion);
        void onLongClick(String username,int postion);
    }
}

基本的RecyclerViewAdapter,要实现的四个方法:
1.自定义MyViewHolder继承RecyclerView.ViewHolder
2.getItemCount() 获取总的条目数 
3.onCreateViewHolder() 创建ViewHolder 
4.onBindViewHolder() 将数据绑定至ViewHolder


RecyclerView排序:

    recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false));


实现RecyclerView动画:

 //实现动画效果
        DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
        defaultItemAnimator.setAddDuration(1000);
        defaultItemAnimator.setRemoveDuration(1000);
         recyclerview.setItemAnimator(defaultItemAnimator);
在DefaultItemAnimator中有Add、Remove、Move、Change四种动画.

需要注意的是,要实现这四种动画效果,数据更新时不能通过:

Adapter.notifyDataSetChanged();

而是通过:

Adapter.notifyItemInserted(int position) 
Adapter.notifyItemRemoved(int position)
Adapter.notifyItemChanged(int position)
Adapter.notifyItemMoved(int fromPosition, int  toPosition)


CardView----xml布局:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    android:foreground="?attr/selectableItemBackground"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    app:cardCornerRadius="5dp"
    android:layout_marginTop="5dp"
    app:cardUseCompatPadding="true"
    android:layout_marginBottom="1dp"
    app:cardPreventCornerOverlap="true"
    >


      <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:layout_width="match_parent"
          android:layout_height="wrap_content"
          android:background="@android:color/white"
          android:padding="5dp">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:orientation="horizontal"
                android:padding="5dp">

                  <TextView
                      android:id="@+id/tv_title"
                      android:layout_width="wrap_content"
                      android:layout_height="wrap_content"
                      android:layout_marginLeft="3dp"
                      android:text="Content"
                      android:textSize="25sp"
                      android:textAllCaps="false"
                      android:textColor="#000000" />
            </LinearLayout>

      </RelativeLayout>


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

CardView基本属性:

app:cardBackgroundColor这是设置背景颜色
app:cardCornerRadius这是设置圆角大小
app:cardElevation这是设置z轴的阴影
app:cardMaxElevation这是设置z轴的最大高度值
app:cardUseCompatPadding是否使用CompatPadding
app:cardPreventCornerOverlap是否使用PreventCornerOverlap
app:contentPadding 设置内容的padding
app:contentPaddingLeft 设置内容的左padding
app:contentPaddingTop 设置内容的上padding
app:contentPaddingRight 设置内容的右padding
app:contentPaddingBottom 设置内容的底padding

/关于在5.0后显示异常问题解决方法
<!-- 在v20和之前的版本中添加内边距,这个属性是为了防止卡片内容和边角的重叠 -->
        app:cardPreventCornerOverlap="true"
<!-- 设置内边距,v21+的版本和之前的版本仍旧具有一样的计算方式 -->

        app:cardUseCompatPadding="true"

Mtext公共代码类:

 快速生成get,set,构造方法:Alt+Insert

public class Mtext {
    private String usertext;
    private int postion;

    public Mtext(String usertext, int postion) {
        this.usertext = usertext;
        this.postion = postion;
    }

    public String getUsertext() {
        return usertext;
    }

    public void setUsertext(String usertext) {
        this.usertext = usertext;
    }
    public int getPostion() {
        return postion;
    }

    public void setPostion(int postion) {
        this.postion = postion;
    }

}

MainActivity代码:

package com.example.administrator.recyclerview;

import android.content.Intent;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btn_add;
    private Button btn_delete;
    private Button btn_list;
    private Button btn_grid;
    private Button btn_flow;
    private RecyclerView recyclerview;
    private LinearLayout linearLayout;
    private MyRecyclerViewAdapter adapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();


        //设置RecyclerView的适配器
        //RecyclerView通过构造方法给RecyclerAdpater适配器传递数据
        adapter = new MyRecyclerViewAdapter(this,Data()); //context,List<Mtext>datas
        recyclerview.setAdapter(adapter);
        //LayoutManager
        recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this, LinearLayoutManager.VERTICAL, false));
//        recyclerview.scrollToPosition(datas.size()-1);
        //实现动画效果
        DefaultItemAnimator defaultItemAnimator = new DefaultItemAnimator();
        defaultItemAnimator.setAddDuration(1000);
        defaultItemAnimator.setRemoveDuration(1000);
         recyclerview.setItemAnimator(defaultItemAnimator);
        //我真tmd机智
       adapter.setListener(new MyRecyclerViewAdapter.MyClickListener() {
           //Item单击事件
           @Override
           public void onClick(String username,int postion) { //postion的作用是防止跳转时进入同一个界面,以及不同操作实现在一个界面上
               Toast.makeText(MainActivity.this,"点击了"+username,Toast.LENGTH_SHORT).show();
                  switch (postion){
                      case 0:
                          Intent intent=new Intent(getApplicationContext(),Okhttpdemo.class);
                          startActivity(intent);
                          break;
                        /*case 1:*/                  }     }
           //Item长按事件
           @Override
           public void onLongClick(String username, final int postion) {   //postion的作用根据int值进行移除
               Snackbar.make(linearLayout, "确定删除" + username + "吗?", Snackbar.LENGTH_LONG)
                       .setAction("确定", new View.OnClickListener() {
                           @Override
                           public void onClick(View view) {
                               //删除该CradView
                               adapter.removeData(postion);
                           }
                       }).show();
           }
       });

    }
    //准备数据源
    public   List<Mtext> Data() {
        List<Mtext>  datas = new ArrayList<>();

        Mtext mtext=new Mtext("Okhttp",0);
        datas.add(mtext);
        Mtext mtext1=new Mtext("FastJson",1);
        datas.add(mtext1);
        return  datas;
    }

    private void initView() {
        setContentView(R.layout.activity_main);
        linearLayout= (LinearLayout) findViewById(R.id.liner);
        btn_add = (Button) findViewById(R.id.btn_add);
        btn_delete = (Button) findViewById(R.id.btn_delete);
        btn_list = (Button) findViewById(R.id.btn_list);
        btn_grid = (Button) findViewById(R.id.btn_grid);
        btn_flow = (Button) findViewById(R.id.btn_flow);
        recyclerview = (RecyclerView) findViewById(R.id.recyclerview);
        //设置点击事件
        btn_add.setOnClickListener(this);
        btn_delete.setOnClickListener(this);
        btn_list.setOnClickListener(this);
        btn_grid.setOnClickListener(this);
        btn_flow.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.btn_add:
                adapter.addData("FastJson",1);
                recyclerview.scrollToPosition(0);
                break;
            case R.id.btn_list:
                //设置List类型效果
                recyclerview.setLayoutManager(new LinearLayoutManager(MainActivity.this,LinearLayoutManager.VERTICAL,false));
                break;
            case R.id.btn_grid:
                //设置Grid类型效果,九宫格
                recyclerview.setLayoutManager(new GridLayoutManager(MainActivity.this, 2, GridLayoutManager.VERTICAL, false));
//                recyclerview.scrollToPosition(99);
                break;
            case R.id.btn_flow:
                //设置瀑布流类型效果
                recyclerview.setLayoutManager(new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL));
                break;
        }
    }
}

好了,到此一个RecyclerView+CradView的demo,就做好了,实现了显示,增加和移除的动画效果,瀑布流,以及单击和长按事件,另外本demo重启后数据是会恢复原样的,是因为List<Mtext>Data()的原因。

推荐一个大神封装的RecyclerView库:https://github.com/CymChad/BaseRecyclerViewAdapterHelper

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值