RecyclerView的基本使用(一)

          RecyclerView的灵活多变,让开发者对于android界面的布局有了更多的方式,也因为recyclerView的灵活多变,android越来越有意思。今天先来介绍recyclerView的基本使用。

RecyclerView官方文档

添加依赖

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

这里要注意,recyclerView的版本要与appCompat的版本一致比较好,我记得我之前报错了,忘记记录下来了,不记得是啥了。

布局文件:

            
            

很多人都说RecyclerView的出现就是为了替代listview和gridView的,我也不清楚到底是不是这样,但是,listView和Gridview用起来真很简单,所以,在平常的一些地方,能用list view和gridView的,就用他们两,我觉得无可厚非,在这次RecyclerView的基本使用介绍中,我们可以利用recyclerView来实现三种布局,Listview格式的,GridView格式的,瀑布流格式的。

首先,不管是ListView还是GridView还是现在要讲解的RecyclerView,都需要一个适配器。所以,我们先来看看recyclerView的最初的适配器是怎样的吧。

这里先举个栗子

    /*最初的适配器是没有viewHolder的,因为要为ItemView设置点击事件,所以这里写了一个ViewHolder继承了
    *RecyclerView.ViewHolder,并重写了它的构造方法。
    * */
    class  ListRecyclerViewAdapter extends RecyclerView.Adapter{
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            return null;
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {

        }

        @Override
        public int getItemCount() {
            return 0;
        }
        class ViewHolder extends RecyclerView.ViewHolder{
            public ImageView imageView;
            public ViewHolder(View itemView) {
                super(itemView);
                imageView= (ImageView) itemView.findViewById(R.id.img_recyclerviewItem);
            }
        }
    }


在上面的代码中可以看到,我们的适配器集成了RecyclerView.Adapter并同时继承了他的三个构造方法。仔细观察这三个构造方法可以发现,第一个方法返回的是一个viewHolder对象,第二个方法接受的是一个ViewHolder对象,所以我们可以大胆猜测,第一个方法返回的recyclerView就返回到了第二个方法的形参中,这一点感觉跟AsyncTask的doInBackground与onPostExcute的用法十分的相似。先撇开这个话题不谈,与BaseAdapter类似,在以前我们初始化BaseAdapter的时候,考虑性能优化,也会在自己写一个viewHolder来缓存我们的view,先不急添加点击事件,我们先让我们的itenView给展现出来,所以继续完善我们的Adapter。

    class  ListRecyclerViewAdapter extends RecyclerView.Adapter{
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView=View.inflate(getApplicationContext(),R.layout.item_recyclerview,null);
            return new ViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.imageView.setImageResource(itemImgs[position]);
        }

        @Override
        public int getItemCount() {
            return itemImgs.length;
        }
        class ViewHolder extends RecyclerView.ViewHolder{
            public ImageView imageView;
            public ViewHolder(View itemView) {
                super(itemView);
                imageView= (ImageView) itemView.findViewById(R.id.img_recyclerviewItem);
            }
        }
    }

与上一步相比较补充的很少,就是在onCreateViewHolder方法中获取我们的itemView,并且将这个itemView封装在viewHolder中返回回去了。然后接下来就是在onBindViewHolder中为我们holder中的数据设置值。onCreateViewHolder和onBindViewHoder在源码中的说明是这样的,recyclerView通过调用它去display指定位置的数据。这个方法应该更新viewHolder中的内容,这个内容是反射位置的条目的内容,翻译有点蹩脚。

        /**
         * Called by RecyclerView to display the data at the specified position. This method should
         * update the contents of the {@link ViewHolder#itemView} to reflect the item at the given
         * position.

好了,基本的recyclerView的Adapter指定好了,那么如何使用呢?代码如下。

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_list);
        //获取控件
        recyclerView=(RecyclerView)findViewById(R.id.list_recycler);
        //如果设置为真,那么适配器的改变不会影响recyclerView的尺寸,官方文档是这么翻译的
        recyclerView.setHasFixedSize(true);
        //设置item增加删除的动画
        recyclerView.setItemAnimator(new DefaultItemAnimator());
        //设置线性布局管理器
        recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
        recyclerView.setAdapter(new ListRecyclerViewAdapter());
    }

是的,这样就可以呈现我们要展示的内容了。大家可以注意到,这里调用了三个方法,setHasFixedSize、setItemAnimator、和setLayoutManager。前面两个方法暂且不聊,而第三个方法,就是我们recyclerView实现ListView格式、GridView格式、瀑布流格式的关键,分别对应的是

LinearLayoutManager,GridLayoutManager,StaggeredGridLayoutManager。


瀑布流的效果如下,有点拉闸。

好了,界面呈现出来了,我们想要像listview和RecyclerView一样为其设置item的点击事件,那么我们就来实现这个功能吧,Adapter是设置点击事件最好的地方

我们修改的adapter代码如下

    static class  ListRecyclerViewAdapter extends RecyclerView.Adapter
    implements View.OnClickListener{
        private static  int[] mItemsImgs;

        public ListRecyclerViewAdapter(int[] imgs) {
            this.mItemsImgs=imgs;
        }
        @Override
        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View itemView=View.inflate(parent.getContext(),R.layout.item_recyclerview,null);
            itemView.setOnClickListener(this);
            return new ViewHolder(itemView);
        }
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            holder.imageView.setImageResource(mItemsImgs[position]);
            holder.itemView.setTag(position);
        }
        @Override
        public int getItemCount() {
            return mItemsImgs.length;
        }
        //声明点击事件
        private   interface OnRecyclerViewItemClickListener{
            void onItemClick(View view,int position);
        }
        private OnRecyclerViewItemClickListener onRecyclerViewItemClickListener=null;
        public void setOnRecyclerViewItemClickListener(OnRecyclerViewItemClickListener listener){
            this.onRecyclerViewItemClickListener=listener;
        }
        @Override
        public void onClick(View view) {
            if(onRecyclerViewItemClickListener!=null){
                onRecyclerViewItemClickListener.onItemClick(view, (Integer) view.getTag());
            }
        }
        //----
        class ViewHolder extends RecyclerView.ViewHolder{
            public ImageView imageView;
            public ViewHolder(View itemView) {
                super(itemView);
                imageView= (ImageView) itemView.findViewById(R.id.img_recyclerviewItem);
            }
        }
    }

可以清楚的看到,代码的改动似乎有点大。是的,的确有点大。

首先,我们实现了View.OnClickListener,实现了他的的onClick方法。

其次,我们创建了一个OnRecyclerViewOnItemClickLister方法,并且定义了他的内部方法为onItemOnClick,这个方法接收两个对象,一个是view,一个是int position。

第三,我们声明了一个onRecyclerViewOnItemClickLister对象。

第四,暴露了一个setOnRecyclerViewItemClickListeners方法,要求传入一个OnRecyclerViewItemClickListener 对象。

第五,我们在onClick方法中调用了onRecyclerViewOnitemClickListener的onItemOnClick方法。

第六,我们在onCreateViewHolder方法中为view设置了一个onClick监听事件。

第七,在onBindViewHolder方法中为view设置tag。

只有通过以上起步,才能实现我们的点击事件,的确是有点麻烦。

最后点击的效果图

源码地址:点击打开链接


你可能感兴趣的:(RecyclerView的基本使用(一))