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

 *本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布   

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

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

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




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

点击打开链接


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

 

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


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

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

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

第一种:

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

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

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

第二种:

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

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

    @Override
    public void onAttachedToRecyclerView(final RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);

        RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
        if(manager instanceof GridLayoutManager) {
            final GridLayoutManager gridManager = ((GridLayoutManager) manager);
            gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                @Override
                public int getSpanSize(int position) {
                    int type = getItemViewType(position);
                    switch (type){
                        case TYPE_SLIDER:
                        case TYPE_TYPE2_HEAD:
                        case TYPE_TYPE3_HEAD:
                            return 6;
                        case TYPE_TYPE2:
                            return 3;
                        case TYPE_TYPE3:
                            return 2;
                        default:
                            return 3;
                    }
                }
            });
        }
    }
liaoinstan大神已经给了具体代码和思路,完美实现功能,非常感谢。


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

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

onCreateViewHolder(ViewGroup parent, int viewType)

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

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

思路图如下:

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

 部分代码如下

  @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        if (viewType == TYPE_TOP) {
               //头部轮播图
            View viewtop = inflater.inflate(R.layout.adapter_slider, parent, false);
            StaggeredGridLayoutManager.LayoutParams params =
                    (StaggeredGridLayoutManager.LayoutParams) viewtop.getLayoutParams();
            params.setFullSpan(true);//最为重要的一个方法,占满全屏,以下同理
            viewtop.setLayoutParams(params);
            return new TypeTopsliderHolder(viewtop);
        } else if (viewType == TYPE_HEADER) {

            View view2 = inflater.inflate(R.layout.item_homepagertypeheader_type, parent, false);

            StaggeredGridLayoutManager.LayoutParams params =
                    (StaggeredGridLayoutManager.LayoutParams) view2.getLayoutParams();
            params.setFullSpan(true);
            view2.setLayoutParams(params);
            return new TypeheadHolder(view2);
        } else if (viewType == TYPE_CENTER) {
            //中间head下面的布局
            View view = inflater.inflate(R.layout.itam_homepageradapter_rv2, parent, false);
            StaggeredGridLayoutManager.LayoutParams params2 =
                    (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
            params2.setFullSpan(true);
            view.setLayoutParams(params2);
            return new TypetypeHolder2(view);

        } else if (viewType == TYPE_CATEGORY) {
//四个快速入口的holder
//这里的TypetypeHolder和上面的TypetypeHolder2 其实可以写成一个holder,这里为了简单,避免引起复用带来的问题,分开了
            View view = inflater.inflate(R.layout.itam_homepageradapter_rv2, parent, false);
            StaggeredGridLayoutManager.LayoutParams params2 =
                    (StaggeredGridLayoutManager.LayoutParams) view.getLayoutParams();
            params2.setFullSpan(true);
            view.setLayoutParams(params2);
            return new TypetypeHolder(view);

        } else if (viewType == TYPE_REFRESH) {
            return new TypeRefresh(inflater.inflate(R.layout.item_raiders2, parent, false));
        } else {

            View viewtop = inflater.inflate(R.layout.adapter_slider, parent, false);
            StaggeredGridLayoutManager.LayoutParams params =
                    (StaggeredGridLayoutManager.LayoutParams) viewtop.getLayoutParams();
            params.setFullSpan(true);
            viewtop.setLayoutParams(params);
            return new TypeTopsliderHolder(viewtop);
        }
    }



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


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


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



你可能感兴趣的:(安卓之Recycleview)