RecycleView和ViewPager一起使用在布局中是经常使用的,而且特别爽,最近遇到了一个复杂的首页布局。参考百度糯米,美团,bilibili等应用,都会发现其首页的布局相对复杂,例如下图bilibili的首页(第二张是demo实现的效果图),可以看到在同一个页面中先是有列表布局出现,然后出现了2列的网格布局,接着3列的网格布局,最后还出现了瀑布流式布局:
这样的效果该怎么做呢?是使用LinearLayoutManager、GridLayoutManager还是StaggeredGridLayoutManager?还是根本不是使用的RecycleView,是用ScrollView硬布局实现的?或者使用了多个RecycleView进行嵌套。首先,我们发现页面的长度是无限长度的,可以不断下拉刷新,所有排除ScrollView的可能,基本断定是使用的是RecyclerView我们注意到同一个页面中出现了3中混合布局的排版,有可能是使用RecycleView进行了2级嵌套,在线性RecycleView中嵌套了网格和瀑布的RecycleView?如果没有进行嵌套的话,有没有办法用一种自定义的布局管理器实现这3种效果呢?会不会是使用了某些3方控件?
查找相关的资源,我觉得使用使用特殊的(自定义)布局管理器最合适,方案如下:
这种方案是我认为最为优秀的做法,它完全符合Google制定的标准:使用布局管理器来管理布局。我们继续观察首页布局的图示,我们真的要为了实现这种混合布局自己去写一个布局管理器吗?我们发现上面出现了列表、网格、瀑布流3种交叉混排的混合布局。我们先把瀑布流放在一边,仔细想想如果我们把网格的列数设置为1列,那不就是一个列表布局吗,也就是说我们使用网格布局管理器就可以做出列表的样式,所以说虽然是说用自定义布局管理器,但实际上不需要我们自定义,GridLayoutManager为我们提供了动态改变每个item所占列数的方法:
gridManager.setSpanSizeLookup(newGridLayoutManager.SpanSizeLookup() {
@OverridepublicintgetSpanSize(intposition) {
returngridManager.getSpanCount();
}
}
getSpanSize方法,返回值就表示当前item占多少列,例如如果我们列数设置的为3列,返回3就表示铺满,也就是和列表一样了。
如图所示,我们给RecyclerView设置一个列数为6的GridLayoutManager,然后再动态地为不同部位的item分别设置SpanSize为6(铺满)、3(1/2)、2(1/3)就行了
那么有朋友就要问了,说好的瀑布流呢?
我查阅了StaggeredGridLayoutManager,发现它并没有提供动态设置所占列的方法,只是在StaggeredGridLayoutManager.LayoutParams中提供了这样一个方法:
LayoutParams.setFullSpan(true);
作用是把当前item的宽度设为full(填满),也就是说如果使用StaggeredGridLayoutManager要么不设置,要么就只能填满,所以无法完成图上的效果,我们也并不是非要完全仿照它,bilibili在最近一次更新后也放弃使用瀑布流式的布局了,统一为列表和网格式混排。
当然如果要实现图上的效果也不是没有办法,只需要换一种方式,改一下item,把设置为FullSpan的item设置为一个多个视图组合的复合item就行了,放个图,代码就不上了: