深入解析RecyclerView

深入解析RecyclerView

  • 前言:这段时间一直在总结代码,书写博客!希望自己技术有所提高,在明年的4月份得到好的实习机会!
(一)介绍RecyclerView
  • RecyclerView到底是什么呢?RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListView和GridView控件的继承者。RecyclerView高度解耦,异常灵活,通过设置不同LayoutManager,ItemDecoration , ItemAnimator实现令人想象不到的效果。首先我们先看一下RecyclerView在我项目中实现的效果图:

         这里写图片描述

         这里写图片描述

【注意】我们可以从中看出RecyclerView可以实现ListView和GridView功能并且成功实现高度定制与解耦!

  • 如果想要控制其显示方式:Linear , grid or stagger ,可以通过布局管理器LayoutManager。
  • 如果想要控制Item间的间隔以及样式,可以通过ItemDecoration。
  • 想要控制Item增删动画,可以通过ItemAnimator。(有默认类)
  • 想要控制Item的点击事件,需要自己设置回调监听事件。
    我来看一下RecyclerView的一些关键类:

1.Datas: 要显示的数据
2.Adapter:适配器,绑定数据集
3.ViewHolder:根据当前的数据保存视图
4.LayoutManager:布局管理器。决定item如何摆放
5.ItemDecoration:勉强理解为item装饰器,可以美化item
6. ItemAnimator:动画(当item被增加,删除,重新摆放时动画才有效)。
7. Listener: 事件。RecyclerView 本身不提供OnItemClickListener 等事件

首先我们来看一下基本的使用方法:


        mAdatper = new MyAdatper(datas);
        mRecyclerView.setAdapter(mAdatper);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());

【注意】可以看出基本的步骤有:1.实例化自定义的Adapter类,2.设置mAdapter ,3.设置Layout ,4.设置ItemDecoration,5.设置ItemAnimator(非必须,有默认动画属性)。

【注意】使用前需要在Gradle上配置:

compile 'com.android.support:recyclerview-v7:23.0.1'

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;

    private List<String> datas = new ArrayList<>();

    private  MyAdatper mAdatper;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);


        initDatas();

        mRecyclerView = (RecyclerView) this.findViewById(R.id.recyclerView);


        mAdatper = new MyAdatper(datas);
        mRecyclerView.setAdapter(mAdatper);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setItemAnimator(new DefaultItemAnimator());


        mAdatper.setOnItemClickListener(new MyAdatper.OnItemClickListener() {
            @Override
            public void onClick(View v, int position, String city) {

                Toast.makeText(MainActivity.this,"city:"+city+",position:"+position,Toast.LENGTH_LONG).show();
            }
        });
    }

    private  void initDatas(){

        datas.add("New York");
        datas.add("Boston");
        datas.add("Washington");
        datas.add("San Francisco");
        datas.add("California");
        datas.add("Chicago");
        datas.add("Houston");
        datas.add("Phoenix");
        datas.add("Philadelphia");
        datas.add("Pennsylvania");
        datas.add("San Antonio");
        datas.add("Austin");
        datas.add("Milwaukee");
        datas.add("Las Vegas");
        datas.add("Oklahoma");
        datas.add("Portland");
        datas.add("Mexico");

    }
}

MyAdapter.java

public class MyAdatper  extends RecyclerView.Adapter<MyAdatper.ViewHolder> {

    private List<String> mDatas;

    private LayoutInflater inflater;

    //设置OnItemClickListener接口,实现对Item的监听
    private  OnItemClickListener listener;

    public void setOnItemClickListener(OnItemClickListener listener){

        this.listener = listener;
    }

    //新建Adapter时往里面添加数据List<String>
    public MyAdatper(List<String> datas){
        mDatas = datas;
    }

    interface  OnItemClickListener{
        void onClick(View v,int position,String city);

    }

    //动态加载Item的布局文件,创建一个ViewHolder
    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        inflater = LayoutInflater.from(parent.getContext());
        View view = inflater.inflate(R.layout.item,parent,false);
        return new ViewHolder(view);
    }

    //把ViewHolder里面的控件进行数据绑定
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {


        holder.textView.setText(mDatas.get(position));

    }
    //得到Item的数量
    @Override
    public int getItemCount() {
        return mDatas.size();
    }
    public  void addData(int position,String city){

        mDatas.add(position,city);
        //通知添加Item
        notifyItemInserted(position);

    }
    public void removeData(int position){
        mDatas.remove(position);
        //通知取出Item
        notifyItemRemoved(position);
    }

    //对布局文件中的控件进行绑定,并在其中对布局文件或者Item建立监听机制
    class  ViewHolder extends  RecyclerView.ViewHolder{
        private TextView textView;
        public ViewHolder(View itemView) {
            super(itemView);

            textView = (TextView) itemView.findViewById(R.id.text);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if(listener !=null){
                        listener.onClick(v,getLayoutPosition(),mDatas.get(getLayoutPosition()));
                    }

                }
            });
        }
    }

}
  • activity_main.xml中的布局文件
<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/recyclerView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

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

</RelativeLayout>
  • item.xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/selector_item_bg"
    android:gravity="center"
    android:padding="20dp"
    >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_gravity="center"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#fff"
        android:textSize="20dp"
        android:padding="20dp"
        android:text="1" />

</LinearLayout>
  • 效果图如下:
    这里写图片描述

【注意】当我们需要对其设置decoration,即各个Item之间的分割线时,需要添加:mRecyclerView.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL_LIST));注意,DividerItemDecoration是RecyclerView.ItemDecoration的实现类,该类很好的实现了RecyclerView添加分割线(当使用LayoutManager为LinearLayoutManager时)。 如果读者需要该类,可以在评论里留下邮箱。

LayoutManager

RecyclerView.LayoutManager吧,这是一个抽象类,好在系统提供了3个实现类:

LinearLayoutManager 现行管理器,支持横向、纵向。 GridLayoutManager 网格布局管理器
StaggeredGridLayoutManager 瀑布就式布局管理器

上面我们已经初步体验了下LinearLayoutManager,接下来看GridLayoutManager。

//mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
        mRecyclerView.setLayoutManager(new GridLayoutManager(this,4));

这里写图片描述

对此需要编写新的DividerGridItemDecoration类,需要的读者在评论里留下邮箱。

ItemAnimator

ItemAnimator也是一个抽象类,系统为我们提供了一种默认的实现类,当Item添加和移除时,添加动画效果很简单:

// 设置item动画
mRecyclerView.setItemAnimator(new DefaultItemAnimator());

在上述的adapter中添加俩个方法:

 public  void addData(int position,String city){

        mDatas.add(position,city);
        //通知添加Item
        notifyItemInserted(position);

    }

    public void removeData(int position){

        mDatas.remove(position);
        //通知取出Item
        notifyItemRemoved(position);
    }
  • 在MainActivity中点击MenuItem触发:
@Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId())
        {
            case R.id.id_action_add:
                mAdatper.addData(0,"new Citiy");
                break;
            case R.id.id_action_delete:
                mAdatper.removeData(1);
                break;
            case R.id.id_action_gridview:
                mRecyclerView.setLayoutManager(new GridLayoutManager(this, 4));
                break;
            case R.id.id_action_listview:
                mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
                break;
            case R.id.id_action_horizontalGridView:
                mRecyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,
                        StaggeredGridLayoutManager.HORIZONTAL));
                break;

        }
        return true;
    }
Onclick方法
  • 系统没有实现对Item的监听,所以需要我们自己定义回调:

    //设置OnItemClickListener接口,实现对Item的监听

    private  OnItemClickListener listener;

    public void setOnItemClickListener(OnItemClickListener listener){
        this.listener = listener;
    }

    interface  OnItemClickListener{
        void onClick(View v,int position,String city);
    }
  • 在ViewHolder中对Item点击触发
 textView = (TextView) itemView.findViewById(R.id.text);

            itemView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {

                    if(listener !=null){
                        listener.onClick(v,getLayoutPosition(),mDatas.get(getLayoutPosition()));
                    }

                }
            });
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值