标题看起来比较拗口啊,直接上图:
项目需求:
1.整个页面需要下拉刷新
2.整个页面可滑动
3.底部数据很多,需要上拉加载更多
因为整个页面需要滑动,所以上面两个横条的内容不能写死,而且,两个横条的内容有时候也会不固定,都是从服务端拿的数据,个数不定。所以不能写成如下布局:
# LinearLayout
#LinearLayout
#RecyclerView(LinearLayoutManager针对不固定的横条数据)
#LinearLayout(grid型数据的标题)
#RecyclerView(GridLayoutManager)
这样的布局写出来,可滑动区域就只在屏幕下半部分,非常不合理!
为了解决整体滑动的问题,我们想到用NestedScollView,这样的局部为:
#NestedScollView
#LinearLayout
#RecyclerView(LinearLayoutManager针对不固定的横条数据)
#LinearLayout(grid型数据的标题)
#RecyclerView(GridLayoutManager)
这样的布局写出来,会存在NestedScollView和RecyclerView滑动冲突的问题,通过下面一行代码:
mRecyclerView.setNestedScrollingEnabled(false);
把滑动交给外部处理。
但是!上拉加载更多整个功能就不容易实现了!遂弃之。
回到最初的起点,为了更好解决上拉加载更多和下拉刷新的问题,为此,我采用一贯的设计思路,整个布局设计为
com.aspsine.swipetoloadlayout.SwipeToLoadLayout
#swipe_refresh_header
#android.support.v7.widget.RecyclerView
#swipe_load_more_footer
#1 下拉刷新通过swipe_refresh_header实现
#2 整个页面可滑动通过RecyclerView实现
#3底部加载更多通过wipe_load_more_footer实现
这时候问题来了!通过一个RecyclerView如果实现上图复杂的布局的,一会是线性的,一会是grid的。
!!!先想到了一个解决方法:
依然使用LinearLayoutManager,然后对于一行有三列数据的处理方法是:
依然写成一个holder,只不过布局是三个View,然后bind数据的时候,一次性带三个model过来,简而言之,把这个三个数据当作一个数据来处理。然后写出来的代码大概是:
不忍直视!!!
山重水复疑无路,柳暗花明又一村!这时候,我在和另一个技术不错的同学聊天时得知,GridLayoutManager有一个属性叫做span,可以非常优雅的解决上述问题!
整个页面使用GridLayoutManager,并且spanCount定为3,但是根据itemType来判定其他holder一个数据所占据的列数,注意,是一个holder占据的列数。于是就有了下面的代码:
意思是:整个布局使用GridLayoutManager,并且每一行默认三列,但是对于 MILIEU/GROUP/RRECOMMEND/LOAD_MORE/HOMETOWN_SUB 这几种type的holder每一个占三列,每一个占三列,而对于 PERSON这个TYPE,holder每一个占一列。
通过这个方法可以非常优雅的解决不同类型布局的问题。
插一句,对于文章开头的图2,可以看到setSpanSizeLookup里拿到positon,可以根据每一个position设置当前holder占据的列数,即通过如下代码:
至此,这个问题很好的解决了,大吉大利,今晚TB!