前奏
前几天面试时候被问到了关于recyclerView的一些问题,虽然项目中也用到过,但用的都是github别人封装好的库,对这个强大无比的控件没有认真的去了解.回来后好好看了看官方的文档及源码,有了初步的认识,先记录一下,后期再更新.
RecyclerView是谷歌在14年io大会上推出的.他有着比listView更强大更灵活的功能. 我们可以通过导入support -v7包来使用它. 为什么说他更灵活更强大呢?因为他整体的架构是一种插拔式的,高度解耦: - 想要控制item的分割线及间距,你可以使用itemDecorator; - 想要给item添加动画效果,你可以使用itemAnimator; - 想要变换item的显示方式,你可以使用layoutManager; - 唯一不足就是item的点击事件需要自己来实现!不过也好实现,可以通过观察者模式在bindViewHolder中实现,或者在onItemTouchListener中来定制click和longClick事件.
适配器写好了,在设置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。
新闻热点
疑难解答