RecycleView的详细介绍

来源:互联网 发布:呼死你软件淘宝有卖吗 编辑:程序博客网 时间:2024/06/02 02:18

RecycleView的简介

 

RecyclerView是一种新的视图组,目标是为任何基于适配器的视图提供相

似的渲染方式。该控件用于在有限的窗口中展示大量数据集,它被作为ListView和GridView控件的继承者。

那么有了ListViewGridView为什么还需要RecyclerView这样的控件呢?整体上看RecyclerView架构,提供了一种插拔式的体验,高度的解耦,异常的灵活,通过设置它提供的不同LayoutManagerItemDecoration , ItemAnimator实现令人瞠目的效果。

· 你想要控制其显示的方式,请通过布局管理器LayoutManager

· 你想要控制Item间的间隔(可绘制),请通过ItemDecoration

· 你想要控制Item增删的动画,请通过ItemAnimator

· 你想要控制点击、长按事件,请自己写(擦,这点尼玛。)

 

 

二、RecycleView的基本使用

 

1、在Gradle中引入RecycleView的依赖库。

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

 

2、在布局文件当中放置我们的RecycleView

<?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="match_parent">

 

    <android.support.v7.widget.RecyclerView

        android:id="@+id/recycle"

        android:layout_width="match_parent"

        android:layout_height="wrap_content"/>

 

</LinearLayout>

 

3、创建适配器类继承RecycleViewAdapter,步骤为:

· 继承RecyclerView.Adapter,并且在Adapter里面声明ViewHolder类继承RecyclerView.ViewHolder最后把自己的ViewHolder类丢进自己的Adapter类的泛型中去

· 在自定义ViewHolder类的构造方法中可以通过ID找到布局的控件,控件需要声明为自定义ViewHolder类的成员变量。

· 实现RecyclerView.Adapter的所有未实现的函数,onCreateViewHolder主要负责加载布局(加载的时候注意要把父布局写到参数里去),创建自定义ViewHolder类的对象;onBindViewHolder主要负责把数据设置到Item的控件中;getItemCount主要负责得到数据的数目

· 最好把数据声明为成员变量在构造函数里面传进来

· 由于RecycleView原生不支持点击事件,需要自己添加接口进行回调。

 

代码如下:

 

public class MyAdapterextends RecyclerView.Adapter<MyAdapter.MyViewHolder> {

 

    List<String> mDatas= null;

    Context mContext = null;

 

    //通过构造函数把要显示的数据读取进来

    public MyAdapter(List<String> mDatas, Context context) {

        this.mDatas= mDatas;

        this.mContext= context;

    }

 

    //相当于ListView中的getView()方法

    @Override

    public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

//      View v = View.inflate(mContext, R.layout.item, null);

 

        LayoutInflater inflater = LayoutInflater.from(mContext);

        //加载布局的时候需要注意要把parent传进去

        View v = inflater.inflate(R.layout.layout_item, parent, false);

 

        MyViewHolder holder = new MyViewHolder(v);

        return holder;

    }

 

    //在这里需要设置显示的数据

    @Override

    public void onBindViewHolder(MyViewHolder holder, int position) {

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

    }

 

    @Override

    public int getItemCount() {

        return mDatas.size();

    }

 

    //自定义ViewHolder必须继承RecyclerView.ViewHolder,在构造函数中进行ID绑定控件,条目监听等

    class MyViewHolder extends RecyclerView.ViewHolder{

 

        TextView tv_num;

 

        public MyViewHolder(final View itemView) {

            super(itemView);

 

            tv_num = (TextView) itemView.findViewById(R.id.tv_num);

            tv_num.setOnClickListener(new View.OnClickListener() {

                @Override

                public void onClick(View v) {

                    if (onItemClickListener!= null) {

                        onItemClickListener.onItemClick(itemView, getLayoutPosition(), mDatas.get(getLayoutPosition()));

                    }

                }

            });

        }

    }

 

    //自定义监听

    private OnItemClickListener onItemClickListener;

 

    public void setOnItemClickListener(OnItemClickListener listener) {

        this.onItemClickListener= listener;

    }

 

    public interface OnItemClickListener{

        void onItemClick(View v, int position, String data);

    }

 

    public void addData(int position, String data) {

        mDatas.add(position, data);

        notifyItemInserted(position);

    }

 

    public void removeData(int position) {

        mDatas.remove(position);

        notifyItemRemoved(position);

    }

 

}

 

4、下面是MainActivity中需要进行的处理。核心的步骤(某些步骤可不分先后)如下:

· 通过ID找到RecyclerView

· RecyclerView设置Adapter

· RecyclerView设置布局管理器,常用的布局管理器有LinearLayoutManager:线性布局,LayoutManager的实现类,类型包括Vertical和HorizontalGridLayoutManager;格子布局,继承自LinearLayoutManager,实现效果类似GridViewStaggeredGridLayoutManager交错的格子布局,同样也是LayoutManager的实现类,类型包括VerticalHorizontal,与GridLayoutManager很相似,不过是交错的格子,也就是宽高不等的格子视图,类似瀑布流的效果。

· RecyclerView设置数据插入、删除的时候的动画效果,这里使用默认的。下面的网址是GitHub上面的开源动画效果:https://github.com/gabrielemariotti/RecyclerViewItemAnimators

· RecyclerView设置Item之间的装饰器,这里也是使用GitHub提供的装饰器,代码会在附件中给出。

代码如下

 

public class MainActivityextends AppCompatActivity{

 

    List<String> datas= null;

    private RecyclerView recyclerView;

    private MyAdapter myAdapter;

 

    @Override

    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

 

        initData();

 

        recyclerView = (RecyclerView) findViewById(R.id.recycle);

        //设置RecycleView的适配器

        myAdapter = new MyAdapter(datas, this);

        recyclerView.setAdapter(myAdapter);

        //设置布局管理器,以渲染出不同的效果

        recyclerView.setLayoutManager(new LinearLayoutManager(this));

        //设置插入、删除数据的动画效果(这里使用默认的动画)

        recyclerView.setItemAnimator(new DefaultItemAnimator());

        //设置每个Item之间的装饰(这里设置为分隔线)

        recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL_LIST));

 

        //设置条目监听,需要自定义接口

        myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {

            @Override

            public void onItemClick(View v, int position, String data) {

                Toast.makeText(MainActivity.this, data, Toast.LENGTH_SHORT).show();

            }

        });

    }

 

    private void initData() {

        datas = new ArrayList<>();

        for (int i= 0; i< 300; i++) {

            datas.add(i+ "");

        }

    }

 

    @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.action_add:

                myAdapter.addData(0, "new data");

                recyclerView.scrollToPosition(0);

                break;

            case R.id.action_delete:

                myAdapter.removeData(0);

                break;

            case R.id.action_gridview:

                recyclerView.setLayoutManager(new GridLayoutManager(this, 4));

                break;

            case R.id.action_listview:

                recyclerView.setLayoutManager(new LinearLayoutManager(this));

                break;

            case R.id.action_staggeredgridview:

                recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,

                        StaggeredGridLayoutManager.VERTICAL));

                break;

 

        }

        return true;

    }

 

}

 

 

三、运行效果

 

 

先上图三张,具体的一些动画效果需要自己体会。

 

对啦,notifyDataSetChanged方法以及弃用了,请注意RecycleView的新规矩:

notifyDataSetChanged() 弃用notifyItemChanged(int position)notifyItemInserted(int position)notifyItemMoved(int fromPosition, int toPosition)notifyItemRemoved(int position)//range系列,多个item的操作notifyItemRangeChanged(int positionStart, int itemCount)notifyItemRangeInserted(int positionStart, int itemCount)notifyItemRangeRemoved(int positionStart, int itemCount) 

补充:可以通过AdaptergetViewType(int position)方法实现多种不同的条目。

具体做法是根据position的不同例如奇数偶数,或者特定值,然后根据viewType参数的不同去inflate不同的item布局即可。

如下图所示: