【Android基础】RecyclerView的设计艺术
来源:互联网 发布:我想开个网络棋牌室 编辑:程序博客网 时间:2024/06/06 03:43
总览
RecyclerView 和 ListView GridView之类比起来 可谓集大成者,通过开放更加功能强大的接口,以一挡十。有如下几点:
强制绑定ViewHolder ——Adapter
ListView的view复用可是需要RD自己封装ViewHolder来实现,而这里强制了ViewHolder的存在,来看看它是怎么做到的吧?
回忆一下ListView的视图循环利用
@Override public View getView(int position, View convertView, ViewGroup parent) { System.out.println("getView " + position + " " + convertView); ViewHolder holder = null; if (convertView == null) { convertView = mInflater.inflate(R.layout.item1, null); holder = new ViewHolder(); holder.textView = (TextView)convertView.findViewById(R.id.text); convertView.setTag(holder); } else { holder = (ViewHolder)convertView.getTag(); } holder.textView.setText(mData.get(position)); return convertView; } ....public static class ViewHolder { public TextView textView; }
Recycler组件提供了convertView ,至于你要不要利用它去复用,那就是你的事情了,新手常常会踩一下这个坑。
RecyclerView怎么做到呢?
当我们继承
RecyclerView.Adapter<VH extends ViewHolder>
去写adapter时候,要覆写的方法如下:
@Overridepublic MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { /** * 之前listview 的viewHolder是非强制的优化措施,在这里已经被融入到基础框架中了 * 来扩大View的重用性,只有在需要创建viewHolder的时候才会被调用,减少对findviewbyId的调用次数 **/ View item = mInflater.inflate(R.layout.layout_recyclerview_item, null); return new MyViewHolder(item);}@Overridepublic void onBindViewHolder(MyViewHolder holder, int position) { /** * 这里是 数据更新到view的地方。 * 我觉的叫做 onBindViewHolder 不妥,ViewHolder只是一个增加view复用的工具而已 * onUpdateView 还差不多。 * 其实干的事情就是根据position来找到对应的数据,然后将数据更新到ViewHolder所hold的view中。 */ //根据position找到数据 String num = mDatas.get(position); //更新数据到ViewHolder所hold的view中 holder.tv.setText(num);}...class MyViewHolder extends RecyclerView.ViewHolder { TextView tv; public MyViewHolder(View itemView) { super(itemView); /** * findViewById 拿到ViewHolder去做掉,封装性更好 **/ tv = (TextView) itemView.findViewById(R.id.id_num); }}
RecyclerView之下:
无需关心ViewHolder的创建时机 在被通知创建ViewHolder的时候创建ViewHolder,无需自己判断convertView是否为空
无需关心ViewHolder的存储,获取 在被通知要更新View的时候更新View,但是这个时候它递过来的是ViewHolder,我们不用去从view.getTag中去拿
你无法忘记使用ViewHolder,因为它是RecyclerView所必须使用到的类。
解决了列表布局的多样性需求——LayoutManager
RecyclerView.LayoutManager吧,这是一个抽象类,好在系统提供了3个实现类:
- LinearLayoutManager 现行管理器,支持横向、纵向。
- GridLayoutManager 网格布局管理器
- StaggeredGridLayoutManager 瀑布就式布局管理器
解决了装饰列表项多样性需求——ItemDecoration
典型的就是:分割线
public static abstract class ItemDecoration { public void onDraw(Canvas c, RecyclerView parent, State state) { onDraw(c, parent); } @Deprecated public void onDraw(Canvas c, RecyclerView parent) { } public void onDrawOver(Canvas c, RecyclerView parent, State state) { onDrawOver(c, parent); } @Deprecated public void onDrawOver(Canvas c, RecyclerView parent) { } @Deprecated public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { outRect.set(0, 0, 0, 0); } public void getItemOffsets(Rect outRect, View view, RecyclerView parent, State state) { getItemOffsets(outRect, ((LayoutParams) view.getLayoutParams()).getViewLayoutPosition(), parent); } }
onDraw
- 在该方法里可以绘制用来装饰每个item的图。
- 不只是分隔线,可以是任何用来装饰item的图。
- 该方法会在每个item绘制之前绘制,所以它有可能会被item的图所覆盖。
- 那怎么知道我应该在哪块区域绘制呢?根据每个item的位置来计算绘制的位置
onDrawOver
- 和onDraw类同,但是该方法会在每个item绘制之后绘制
getItemOffsets
- 类似padding ,margin, 拿分隔线来说,每增加一个分隔线都会对原来的item的布局产生影响,每个item相对之前都会产生一定的偏移量了。
如下,垂直列表中,增加分隔线对每个item高度上偏移量影响。
@Override public void getItemOffsets(Rect outRect, int itemPosition, RecyclerView parent) { outRect.set(0, 0, 0, mDivider.getIntrinsicHeight()); }
解决了列表项的动画多样性需求——ItemAnimator
目前官方只提供了:DefaultItemAnimator
github也开源了一些动画:
https://github.com/gabrielemariotti/RecyclerViewItemAnimators/tree/master
UML设计图
Demo
https://github.com/jason2code/MyAndroidDemos/tree/master/app/src/main/java/com/android/demos/jason/myandroiddemos/uiRecyclerView
参考
Android RecyclerView 使用完全解析 体验艺术般的控件
ListView中convertView和ViewHolder的工作原理
- 【Android基础】RecyclerView的设计艺术
- 【Android基础】从属性动画看代码设计的艺术
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- Android RecyclerView 使用完全解析 体验艺术般的控件
- 2017寒假测试
- 三星高层正面回应 Note7爆炸事件,表态将加强后续产品安全管理
- JAVA源码分析Collection之Map
- 关于Java的语言问题汇总
- 9.3.6
- 【Android基础】RecyclerView的设计艺术
- 博为峰Java技术文章 ——JavaSE Swing JPanel II
- truncate 和 delete的区别
- Qt学习笔记-----QListWidget,QTableWidget和QTreeWidget
- 实践SEH攻击和虚函数攻击
- CF 238D Tape Programming
- android studio 在 真机调试 时device offline waiting for debugger
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- Android控件绑定代码快速生成工具