alibaba/vlayout: Project vlayout is a powerfull LayoutManager extension for RecyclerView, it provides a group of layouts for RecyclerView. Make it able to handle a complicate situation when grid, list and other layouts in the same recyclerview.
翻译:
阿里巴巴/vlayout:项目vlayout是一个针对Reclerview组件的强大的LayoutManager(布局管理器)的扩展,它为Reclerview组件提供了一组的布局。使它能够处理一个复杂的情况,当网格,列表和其他布局在同一个Reclerview组件中时。
现在这个框架发展的很好,逐步扩充为一个功能更加完善的框架:http://tangram.pingguohe.net/
通过向Reclerview组件提供自定义的LayoutManager,VirtualLayout能够优雅地在单个视图上布局具有不同样式的子视图。自定义LayoutManager管理一系列的layoutHelpers,其中每个LayoutManager实现特定位置范围项的特定布局逻辑。顺便说一句,还支持实现定制的layoutHelper并将其提供到框架中。
对于Gradle:
implementation 'com.alibaba.android:vlayout:1.0.9'
final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
//初始化布局管理器
final VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
提供一个合理的回收池大小到您的RecycledView,因为默认值可能不符合您的情况,并导致屏幕滚动时重新创建视图。
RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
recyclerView.setRecycledViewPool(viewPool);
//设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建View)
viewPool.setMaxRecycledViews(0, 10);
注意:上面的演示代码仅用type=0修改项目的循环池大小,它在适配器中有多个类型,您应该更新每个类型的循环池大小。
DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager,hasConsistItemType);
recyclerView.setAdapter(delegateAdapter);
//设置自适配器集合
delegateAdapter.setAdapters(adapters);
//或者设置单独的适配器
CustomAdapter customAdapter = new CustomAdapter(data, new GridLayoutHelper());
//代理适配器添加子适配器
delegateAdapter.addAdapter(customAdapter);
// call notify change when data changes
adapter.notifyDataSetChanged();
注意:何时hasConsistItemType = true
,在不同的子适配器中具有相同类型值的项共享相同的类型,它们的视图将在滚动期间重用。什么时候hasConsistItemType = false
,在不同的子适配器中具有相同类型值的项不会在内部共享相同的类型。
VirtualLayoutAdapter
并实现它,以便对您的业务代码进行深入的组合。public class MessageAdapter extends VirtualLayoutAdapter {
......
}
MyAdapter msgAdapter = new MessageAdapter(layoutManager);
//创建存放layoutHelper的集合
List helpers = new LinkedList<>();
//创建LayoutHelper对象
GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4);
gridLayoutHelper.setItemCount(25);
//添加到集合
helpers.add(gridLayoutHelper);
//创建LayoutHelper对象
GridLayoutHelper gridLayoutHelper2 = new GridLayoutHelper(2);
gridLayoutHelper2.setItemCount(25);
//添加到集合
helpers.add(gridLayoutHelper2);
//将LayoutHelper对象集合设置到适配器
msgAdapter.setLayoutHelpers(helpers);
//为RecyclerView设置适配器
recyclerView.setAdapter(myAdapter);
注意:当适配器的数据发生变化时,需要调用setLayoutHelpers()方法
。
推荐关于:RecyclerView回收和复用机制分析:https://www.jianshu.com/p/467ae8a7ca6e
1 VirtualLayoutAdapter
* 定义:数据适配器。继承自系统的Adaper
* 作用:创建组件 & 绑定数据到组件
* 额外:定义了两个接口:
* getLayoutHelper():用于返回某个位置组件对应的一个 LayoutHelper
* setLayoutHelpers():调用此方法设置整个页面所需要的一系列 LayoutHelper
* 这两方法的具体实现委托给 VirtualLayoutManager 完成
2 VirtualLayoutManager
* 定义:布局管理器。继承自系统的 LinearLayoutManager
* 作用:
* 在 RecyclerView 加载组件或者滑动时调用 VirtualLayoutManager 的 layoutChunk(),返回当前还有哪些空白区域可摆放组件
* 管理 LayoutHelper 列表
* 额外:实现了 VirtualLayoutAdapter 的 getLayoutHelper() & setLayoutHelpers()
3 LayoutHelper
* 定义:LayoutHelper 寻找器
* 作用:根据页面状态 寻找对应的 LayoutHelper 并返回给 VirtualLayoutManager
* VirtualLayoutManager 会持有一个 LayoutHelperFinder
* 当 layoutChunck() 被调用时会传入一个位置参数,告诉 VirtualLayoutManager 当前要布局第几个组件
* VirtualLayoutManager 通知持有的 LayoutHelperFinder 找到传入参数位置对应的 LayoutHelper(每个 LayoutHelper 都会绑定它负责的布局区域的起始位置和结束位置)
4 LayoutHelperFinder
* 定义:布局协助器
* 作用:负责具体的布局逻辑
5 MarginLayoutHelper
* 定义:继承自 LayoutHelper
* 作用:扩展 LayoutHelper,提供了布局常用的 内边距padding、外边距margin 的计算功能
6 BaseLayoutHelper
* 定义:MarginLayoutHelper 的第一层具体实现
* 作用:填充 当前LayoutHelper 在屏幕范围内的具体区域 背景色、背景图等逻辑
7 子LayoutHelper
* 定义:MarginLayoutHelper 的第二层具体实现
* 作用:负责具体的布局逻辑
* 每种 子LayoutHelper 负责一种布局逻辑
* 重点实现了 beforeLayout()、doLayout()、afterLayout()
* 特别是 doLayout():会获取一组件,并对组件进行尺寸计算、界面布局
* V - Layout 默认实现了10种默认布局:(对应同名的LayoutHelper)
* 特别注意:
* 每一种 LayoutHelper 负责布局一批组件范围内的组件,不同组件范围内的组件之间,如果类型相同,可以在滑动过程中回收复用。因此回收粒度比较细,且可以跨布局类型复用.
* 支持扩展外部:即注册新的 LayoutHelper,实现特殊的布局方式。下面会详细说明