Recycleview实现复杂页面 三种以上布局 瀑布流 多布局 scrollview嵌套recyclerView 显示不全 滑动冲突 之进阶终极篇

时间:2024-02-20 14:31:41

 相信很多安卓开发的朋友,尤其是刚从事安卓开发的朋友, 当产品经理递过来一张复杂页面的设计图时 , 都会有一种茫然的感觉 , 在心里想着如何实现 , 然后网上搜索如何实现复杂布局页面,当初我也是这么过来的, 可以说踩了很多很大的坑 ,  所以决定写下这篇博客 ,  供各位猿猿参观 , 想相信看完此篇 , 绝对是最后一篇 ,  不用再找了 , 当然 此篇为进阶篇 。 如果你对recycleview 还不熟悉 , 建议先了解recycleview , 熟悉其基本使用。如果有问题 , 欢迎加QQ群 661614986。

言归正传, 先来看一下效果图:

 

 

 

 

 

 gif录出来 有点怪 , 所以就截图了,源码已放入github

点击打开链接

 

下面我来分析一下这种复杂界面的具体实现思路, 当然这里非常感谢 奋斗  liaoinstan 大神的文章 http://blog.csdn.net/liaoinstan/article/details/52671101,朋友可以看一下 , 最初我也是看了此篇 , 但是此篇并非完美, 在此我进一步总结一下 。

 

首先我们来做一个分水岭, 就是布局中上拉加载的布局是否是瀑布流,

 

1、如果不是瀑布流, 那就很简单了,借鉴一下liaoinstan的图片,

如果实现此图, liaoinstan给了如下两种方案,

第一种:

 这里recycleview5 应该还是列表管理器, 懒得画图了,意思一样 。

这种方案构思就是recycleview里面嵌套多recycleview,构思简单,编写也是行如流水,能够实现需求,但是问题来了,以下是重点,这种多嵌套的写法,在上拉加载的时候,拉到后面基本就会很卡,就算释放glide(或者其他图片加载框架)的内存也是释放不掉,直至oom或者卡死不动,所以这种嵌套思路只适合没有加载更多的的情况。

第二种:


这中思路里面最重要的方法就是

 

[java] view plain copy
  1. @Override  
  2. public void onAttachedToRecyclerView(final RecyclerView recyclerView) {  
  3.     super.onAttachedToRecyclerView(recyclerView);  
  4.   
  5.     RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();  
  6.     if(manager instanceof GridLayoutManager) {  
  7.         final GridLayoutManager gridManager = ((GridLayoutManager) manager);  
  8.         gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {  
  9.             @Override  
  10.             public int getSpanSize(int position) {  
  11.                 int type = getItemViewType(position);  
  12.                 switch (type){  
  13.                     case TYPE_SLIDER:  
  14.                     case TYPE_TYPE2_HEAD:  
  15.                     case TYPE_TYPE3_HEAD:  
  16.                         return 6;  
  17.                     case TYPE_TYPE2:  
  18.                         return 3;  
  19.                     case TYPE_TYPE3:  
  20.                         return 2;  
  21.                     default:  
  22.                         return 3;  
  23.                 }  
  24.             }  
  25.         });  
  26.     }  
  27. }  

liaoinstan大神已经给了具体代码和思路,完美实现功能,非常感谢。

 

2.如果需求是带瀑布流的

那么,第一种情况里面的 onAttachedToRecyclerView方法瀑布流管理器里面就不存在,因此无法使用,只能另寻他法,liaoinstan大神推荐TwowayView能实现上图这种效果但是, 呵呵,不好意思,当你用TwowayView写实际应用时, 需要网络加载时, 问题出现了,那就是你来回下拉刷新几次,布局上面就会有一块白的空白区域, 直至最后你的布局完全看不见, 只剩下一片白 ,我没有解决此问题。当时我写我们公司的应用时, 写到这里的时候,我就一脸懵逼了, 然后就用最最古老的办法,直接scrollview里面嵌套几个recycleview,写到最后还是意料之中出现问题了,上拉加载到最后还是会卡顿,而且在6.0以上 高度总是有问题。
到这里,大哭大哭大哭我差点想和产品说我们不用瀑布流好不好,但我又从新搜了一下,在瀑布流管理器里面有LayoutParams.setFullSpan(true);方法,在 

[java] view plain copy
  1. onCreateViewHolder(ViewGroup parent, int viewType)  

 总体思路就是,把下面的瀑布流部分作为一种type,其他无需加载更多的布局放在recycleview里面

使用此方法使这一行占满全屏,这是我到现在总结出来的最好实现方式。

思路图如下:


 部分代码如下

 

[java] view plain copy
  1.   @Override  
  2.     public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {  
  3.         if (viewType == TYPE_TOP) {  
  4.                //头部轮播图  
  5.             View viewtop = inflater.inflate(R.layout.adapter_slider, parent, false);  
  6.             StaggeredGridLayoutManager.LayoutParams params =  
  7.                     (StaggeredGridLayoutManager.LayoutParams) viewtop.getLayoutParams();  
  8.             params.setFullSpan(true);//最为重要的一个方法,占满全屏,以下同理  
  9.             viewtop.setLayoutParams(params);  
  10.             return new TypeTopsliderHolder(viewtop);  
  11.         } else if (viewType == TYPE_HEADER) {  
  12.   
  13.             View view2 = inflater.inflate(R.layout.item_homepagertypeheader_type, parent, false);  
  14.   
  15.             StaggeredGridLayoutManager.LayoutParams params =  
  16.                     (StaggeredGridLayoutManager.LayoutParams) view2.getLayoutParams();  
  17.             params.setFullSpan(true);  
  18.             view2.setLayoutParams(params);  
  19.             return new TypeheadHolder(view2);  
  20.         } else if (viewType == TYPE_CENTER) {  
  21.             //中间head下面的布局  
  22.             View view = inflater.inflate(R.layout.itam_homepageradapter_rv2, parent, false);  
  23.             StaggeredGridLayoutManager.LayoutParams params2 =  
  24.                     (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();  
  25.             params2.setFullSpan(true);  
  26.             view.setLayoutParams(params2);  
  27.             return new TypetypeHolder2(view);  
  28.   
  29.         } else if (viewType == TYPE_CATEGORY) {  
  30. //四个快速入口的holder  
  31. //这里的TypetypeHolder和上面的TypetypeHolder2 其实可以写成一个holder,这里为了简单,避免引起复用带来的问题,分开了  
  32.             View view = inflater.inflate(R.layout.itam_homepageradapter_rv2, parent, false);  
  33.             StaggeredGridLayoutManager.LayoutParams params2 =  
  34.                     (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();  
  35.             params2.setFullSpan(true);  
  36.             view.setLayoutParams(params2);  
  37.             return new TypetypeHolder(view);  
  38.   
  39.         } else if (viewType == TYPE_REFRESH) {  
  40.             return new TypeRefresh(inflater.inflate(R.layout.item_raiders2, parent, false));  
  41.         } else {  
  42.   
  43.             View viewtop = inflater.inflate(R.layout.adapter_slider, parent, false);  
  44.             StaggeredGridLayoutManager.LayoutParams params =  
  45.                     (StaggeredGridLayoutManager.LayoutParams) viewtop.getLayoutParams();  
  46.             params.setFullSpan(true);  
  47.             viewtop.setLayoutParams(params);  
  48.             return new TypeTopsliderHolder(viewtop);  
  49.         }  
  50.     }  



 

这个方法 在大神的文章里 只是 副作用的 提了一下, 光想着TwowayView 了 所以没在意 ,最后还是此方法解决了这种需求。

 

我的线上项目为[空艺术,朋友可以点击下载看一下效果](http://a.app.qq.com/o/simple.jsp?pkgname=com.happyo2o.artexhibition),首页就是这个原理实现的,大家可以看一下效果。

 

总结:本人只是理论性的总结了复杂布局的实现方式,以及一些坑 , 避免各位浪费时间和精力 ,鄙人在此献丑了,代码已经全部上传,github项目源码 欢迎star , 转载  , 万分感谢 。 

--------------------- 本文来自 南岸青栀 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/jiankeufo/article/details/79496594?utm_source=copy