RecyclerView 初探

来源:互联网 发布:fm自建球员数据锁定 编辑:程序博客网 时间:2024/06/14 00:34

前奏

前几天面试时候被问到了关于recyclerView的一些问题,虽然项目中也用到过,但用的都是github别人封装好的库,对这个强大无比的控件没有认真的去了解.回来后好好看了看官方的文档及源码,有了初步的认识,先记录一下,后期再更新.

概述

RecyclerView是谷歌在14年io大会上推出的.他有着比listView更强大更灵活的功能.
我们可以通过导入support -v7包来使用它.
为什么说他更灵活更强大呢?因为他整体的架构是一种插拔式的,高度解耦:
- 想要控制item的分割线及间距,你可以使用itemDecorator;
- 想要给item添加动画效果,你可以使用itemAnimator;
- 想要变换item的显示方式,你可以使用layoutManager;
- 唯一不足就是item的点击事件需要自己来实现!不过也好实现,可以通过观察者模式在bindViewHolder中实现,或者在onItemTouchListener中来定制click和longClick事件.

基本使用

我们来看看recyclerView的基本使用,先写个最基本的adapter吧.
class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {        @Override        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {          //在这个方法中加载item布局,创建viewHolder对象并return             return new RvViewHolder(View.inflate(MainActivity.this,R.layout.item_layout,null));        }        @Override        public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        //在这个方法中通过holder获取item控件,绑定数据            RvViewHolder viewHolder = (RvViewHolder) holder;            viewHolder.mTv.setText("hello world" + position);        }        @Override        public int getItemCount() {            return data == null ? 0 : data.length;        }        //viewHolder 获取item布局中的控件        class RvViewHolder extends RecyclerView.ViewHolder{            private final TextView mTv;            public RvViewHolder(View itemView) {                super(itemView);                //这里的itemView就是onCreateViewHolder中加载的view对象                mTv = (TextView) itemView.findViewById(R.id.tv_item);            }        }    }

适配器写好了,在设置adapter前,我们还要先给recyclerView设置一个layoutManager,官方对layoutManager的解释是: LayoutManager负责在RecyclerView中测量和定位项目视图,以及确定何时回收用户不再可见的项目视图的策略。 通过更改LayoutManager,RecyclerView可用于实现标准垂直滚动列表,统一网格,交错网格,水平滚动集合等。 提供了几个库存布局管理器供一般使用。
我们可以通过配置不同的layoutManager来设置不同的显示效果:linearLayoutManager(竖直和水平效果)、GridLayoutManager(表格效果类似gridView)、StaggeredGridLayoutManager(瀑布流)。

recyclerView.setLayoutManager(new LinearLayoutManager(mContext,LinearLayoutManager.VERTICAL,false));recyclerView.setAdapter(new MyAdapter());
这样就实现了一个类似listView的效果啦!

实现多类型item及item点击事件:

public class RvAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {    private Context mContext;    private ArrayList<DataBean> mDatas;    private static final int ITEM_IMAGE = 0;    private static final int ITEM_BUTTON = 1;    private static final int ITEM_TEXT = 2;    private OnItemClickListener mOnItemClickListener;    public void setOnItemClickListener(OnItemClickListener listener){        mOnItemClickListener = listener;    }    //item点击事件的接口    public interface OnItemClickListener{        void onItemClick(View view, int position);        void onItemLongClick(View view, int position);    }    public RvAdapter(Context context,ArrayList<DataBean> data) {        mContext = context;        mDatas = data;    }    @Override    public int getItemViewType(int position) {        //在数据源中添加了不同类型item的相应标记        return mDatas == null ? super.getItemViewType(position) : mDatas.get(position).type;    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        //根据viewType来创建相应的viewHolder        switch (viewType){            case ITEM_IMAGE:                return new ViewHolderImage(View.inflate(mContext, R.layout.item_image,null));            case ITEM_BUTTON:                return new ViewHolderButton(View.inflate(mContext,R.layout.item_button,null));            case ITEM_TEXT:                return new ViewHolderText(View.inflate(mContext,R.layout.item_layout,null));        }        return null;    }    @Override    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {        if (mDatas == null) {            return;        }        switch (mDatas.get(position).type){            case ITEM_IMAGE:                final ViewHolderImage holderImage = (ViewHolderImage) holder;                holderImage.mIv.setImageResource(R.mipmap.ic_launcher);                //item点击事件的示例                if (mOnItemClickListener != null) {                    holderImage.mIv.setOnClickListener(new View.OnClickListener() {                        @Override                        public void onClick(View view) {                            //通过getLayoutPosition来获取当前的位置                            mOnItemClickListener.onItemClick(view,holderImage.getLayoutPosition());                        }                    });                    holderImage.mIv.setOnLongClickListener(new View.OnLongClickListener() {                        @Override                        public boolean onLongClick(View view) {                            mOnItemClickListener.onItemLongClick(view,holderImage.getLayoutPosition());                            return false;                        }                    });                }                break;            case ITEM_BUTTON:                ViewHolderButton holderButton = (ViewHolderButton) holder;                holderButton.mBt.setText(position + "我是button");                break;            case ITEM_TEXT:                ViewHolderText holderText = (ViewHolderText) holder;                holderText.mTv.setText("我是text");                break;        }    }    @Override    public int getItemCount() {        return mDatas == null?  0 : mDatas.size();    }    class ViewHolderImage extends RecyclerView.ViewHolder{        private final ImageView mIv;        public ViewHolderImage(View itemView) {            super(itemView);            mIv = (ImageView) itemView.findViewById(R.id.iv2_item);        }    }    class ViewHolderButton extends RecyclerView.ViewHolder{        private final Button mBt;        public ViewHolderButton(View itemView) {            super(itemView);            mBt = (Button) itemView.findViewById(R.id.btn_item);        }    }    class ViewHolderText extends RecyclerView.ViewHolder{        private final TextView mTv;        public ViewHolderText(View itemView) {            super(itemView);            mTv = (TextView) itemView.findViewById(R.id.tv_item);        }    }}

这样就可以在外部给item设置点击事件啦!添加头布局脚布局也是同理,暂时先不实现…弄别的去了…

ItemDecorator用法:
当我们调用mRecyclerView.addItemDecoration()方法添加decoration的时候,RecyclerView在绘制的时候,去会绘制decorator,
即调用该类的onDraw和onDrawOver方法,

onDraw方法先于drawChildren,onDrawOver在drawChildren之后,一般我们选择复写其中一个即可。
getItemOffsets 可以通过outRect.set()为每个Item设置一定的偏移量,可以分别设置上下左右.主要用于绘制Decorator。

0 0
原创粉丝点击