1. 写在前面
为何要学习自定义 LayoutManger,在原来的基础上 无法满足怪异的奇葩的需求的前提下,我们就需要动手写一个或者改现成的代码了,至少你需要了解或者知道;
比如下面这几种,或者其它 更 怪异的 奇葩的 方式:
这就需要我们具备一定的知识,不然无从下手去修改的;
下面我们将围绕一个简单的 栗子 展开,讲解下 自定义 LayoutManger 需要关注的一些方法还有细节问题;
都9102年,我们就废话少说,开始吧,进入正题… …
2. 重新认识 RecyclerView.LayoutManager
以前我们只是知道如何使用 LinearLayoutManager,GridLayoutManager,那么接下来我们将讨论自定义LayoutManger;
继承XX
你可以继承 RecyclerView.LayoutManager 或者其它来修改代码都是可以的喔!
class TestLayoutmanger extends RecyclerView.LayoutManager
class TestLayoutmanger extends LinearLayoutManager
class TestLayoutmanger extends GridLayoutManager
关键函数
- generateDefaultLayoutParams()
// 这是给子Item View 使用的,只需要默认返回这个就OK了
@Override
public RecyclerView.LayoutParams generateDefaultLayoutParams() {
return new RecyclerView.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT);
// 你要返回 ViewGroup.LayoutParams.FILL_PARENT(宽/高) 也是可以
// 具体参考你的 需要修改的样式以及业务要求吧.
// 这里关于测量onMeasure的内容我就不多讲解了,感兴趣的可以去看看 RecyclerView的onMeasure源码;
// 测量想要了解的可以参考这篇文章: https://blog.csdn.net/qw85525006/article/details/88960990
}
- onLayoutChildren()
// onLayoutChildren 方法,类似 ViewGroup 的 onLayout() 方法.
@Override
public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
// 所有的View先从RecyclerView中detach掉,然后标记为"Scrap"状态,放入 Scrap Heap或Recycle Pool 来提高复用效率.
detachAndScrapAttachedViews(recycler);
// 处理需要显示的的控件
final int itemCount = getItemCount();
for (int i = start; i < end; i++) {
// 从缓存 或 创建 返回一个 view.
final View scrap = recycler.getViewForPosition(index);
addView(scrap);
measureChildWithMargins(scrap, 0, 0);
layoutDecoratedWithMargins(scrap, ... ...)
}
}
// 对于detachAndScrapAttachedViews与getViewForPosition 缓存的了解可以参考这篇文章:https://blog.csdn.net/qw85525006/article/details/91127988
我们已经基本完成一个自定义LayoutManger,但是运行发现,还是有一些问题,无法滚动哈!!!而且使用 getItemCount 也有问题哈!!!该这么办?那我们继续吧… …
资料推荐
关于Android RecyclerView的那些开源LayoutManager https://zhuanlan.zhihu.com/p/26003028
Building a RecyclerView LayoutManager http://wiresareobsolete.com/2014/09/building-a-recyclerview-layoutmanager-part-1/