vlayout_vlayout 实现横向滑动布局 - CSDN
精华内容
参与话题
  • Vlayout使用详细介绍

    千次阅读 2018-01-08 19:16:07
    Vlayout使用详细介绍 目录介绍 1.Vlayout简单介绍 2.主要功能介绍 2.1 主要功能的思维导图 2.2 主要功能说明 .使用方法与案例 3.1 初始化 3.2 设置回收复用池 3.3 设置RecycleView适配器 3.4 ...

    Vlayout使用详细介绍

    目录介绍

    • 1.Vlayout简单介绍
    • 2.主要功能介绍
    • 2.1 主要功能的思维导图
    • 2.2 主要功能说明
    • .使用方法与案例
    • 3.1 初始化
    • 3.2 设置回收复用池
    • 3.3 设置RecycleView适配器
    • 3.4 添加模块的adapter
    • 3.5 将所有adapter绑定到RecycleView
    • 4.相关代码说明
    • 4.1 VirtualLayoutAdapter
    • 4.2 VirtualLayoutManager
    • 4.3 LayoutHelper
    • 4.4 LayoutHelperFinder
    • 4.5 MarginLayoutHelper
    • 4.6 BaseLayoutHelper
    • 4.7 子LayoutHelper
    • 5.相关属性介绍
    • 5.1 LayoutHelper方法说明
    • 5.1.1 margin, padding
    • 5.1.2 dividerHeight
    • 5.1.3 aspectRatio
    • 5.1.4 bgColor, bgImg
    • 5.1.5 weights
    • 5.1.6 vGap, hGap
    • 5.1.7 spanCount, spanSizeLookup
    • 5.1.8 autoExpand
    • 5.1.9 lane
    • 5.2 fix类型的LayoutHelper方法说明
    • 5.2.1 fixAreaAdjuster
    • 5.2.2 alignType, x, y
    • 5.2.3 showType
    • 5.2.4 stickyStart, offset
    • 6.存在的bug
    • 7.源码分析
    • 8.关于其他更多
    • 8.1 关于版本更新说明
    • 8.2 关于我的博客

    好消息

    • 博客笔记大汇总【16年3月到至今】,包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期更新维护并且修正,持续完善……开源的文件是markdown格式的!同时也开源了生活博客,从12年起,积累共计47篇[近20万字],转载请注明出处,谢谢!
    • 链接地址:https://github.com/yangchong211/YCBlogs
    • 如果觉得好,可以star一下,谢谢!当然也欢迎提出建议,万事起于忽微,量变引起质变!

    0.本人写的综合案例

    1.Vlayout简单介绍

    • 阿里的开源框架,地址是:https://github.com/alibaba/vlayout/
    • VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一整套布局方案和布局间的组件复用的问题。

    2.主要功能介绍

    2.1 主要功能思维导图
    2.2 主要功能说明
    • 默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等
    * 1:LinearLayoutHelper: 线性布局
    * 2:GridLayoutHelper: Grid布局, 支持横向的colspan
    * 3:FixLayoutHelper: 固定布局,始终在屏幕固定位置显示
    * 4:ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等
    * 5:FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置
    * 6:ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值
    * 7:SingleLayoutHelper: 通栏布局,只会显示一个组件View
    * 8:OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素
    * 9:StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底
    * 10:StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度
    

    3.使用方法与案例

    3.0 具体可以参考我的实际案例:https://github.com/yangchong211/LifeHelper
    3.1 初始化
    • 创建VirtualLayoutManager对象,与RecycleView绑定
    //创建VirtualLayoutManager对象
    VirtualLayoutManager layoutManager = new VirtualLayoutManager(activity);
    recyclerView.setLayoutManager(layoutManager);
    
    3.2 设置回收复用池
    • 设置回收复用池大小
    //设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View)
    RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
    recyclerView.setRecycledViewPool(viewPool);
    viewPool.setMaxRecycledViews(0, 20);
    
    3.3 设置RecycleView适配器
    • 设置 V - Layout的Adapter有两种方式:
      • 方式1:继承 自 DelegateAdapter
      • 方式2:继承 自 VirtualLayoutAdapter
    • 目前只讨论方式1:继承 自 DelegateAdapter
      • 定义:DelegateAdapter是V - Layout专门为管理 LayoutHelper定制的 Adapter
      • 继承自VirtualLayoutAdapter
      • 作用:通过管理不同布局的Adapter,继而管理不同的 LayoutHelper,从而实现使用不同组合布局
      • 特别注意:虽不可直接绑定LayoutHelper,但是它内部有一个继承自RecyclerView.Adapter的内部类Adapter可以绑定LayoutHelper;
      • 即通过一个List把绑定好的Adapter打包起来,再放去DelegateAdapter,这样就可以实现组合使用不同的布局
    • 具体做法:
    //设置适配器
    DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, true);
    recyclerView.setAdapter(delegateAdapter
    
    /**
     * ================================================
     * 作    者:杨充
     * 版    本:1.0
     * 创建日期:2017/9/18
     * 描    述:Vlayout框架基类适配器
     * 修订历史:
     * ================================================
     */
    public class BaseDelegateAdapter extends DelegateAdapter.Adapter<BaseViewHolder> {
    
        private LayoutHelper mLayoutHelper;
        private int mCount = -1;
        private int mLayoutId = -1;
        private Context mContext;
        private int mViewTypeItem = -1;
    
        protected BaseDelegateAdapter(Context context, LayoutHelper layoutHelper, int layoutId, int count, int viewTypeItem) {
            this.mContext = context;
            this.mCount = count;
            this.mLayoutHelper = layoutHelper;
            this.mLayoutId = layoutId;
            this.mViewTypeItem = viewTypeItem;
        }
    
        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return mLayoutHelper;
        }
    
        @Override
        public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            if (viewType == mViewTypeItem) {
                return new BaseViewHolder(LayoutInflater.from(mContext).inflate(mLayoutId, parent, false));
            }
            return null;
        }
    
        @Override
        public void onBindViewHolder(BaseViewHolder holder, int position) {
    
        }
    
        /**
         * 必须重写不然会出现滑动不流畅的情况
         */
        @Override
        public int getItemViewType(int position) {
            return mViewTypeItem;
        }
    
        //条目数量
        @Override
        public int getItemCount() {
            return mCount;
        }
    }
    
    3.4 添加模块的LayoutHelper
    • 这里代码以LinearLayoutHelper为例子。详细可以参考我的案例
    BaseDelegateAdapter titleAdapter = new BaseDelegateAdapter(activity, new LinearLayoutHelper(),
        R.layout.view_vlayout_title, 1, Constant.viewType.typeTitle) {
        @Override
        public void onBindViewHolder(BaseViewHolder holder, int position) {
            super.onBindViewHolder(holder, position);
            holder.setText(R.id.tv_title, title);
        }
    };
    
    3.5 将生成的LayoutHelper 交给Adapter,并绑定到RecyclerView 对象
    • 相关代码如下所示:
    private void initRecyclerView() {
        DelegateAdapter delegateAdapter = presenter.initRecyclerView(recyclerView);
        //把轮播器添加到集合
        BaseDelegateAdapter bannerAdapter = presenter.initBannerAdapter();
        mAdapters.add(bannerAdapter);
    
        //初始化九宫格
        BaseDelegateAdapter menuAdapter = presenter.initGvMenu();
        mAdapters.add(menuAdapter);
    
        //初始化
        BaseDelegateAdapter marqueeAdapter = presenter.initMarqueeView();
        mAdapters.add(marqueeAdapter);
    
        //初始化标题
        BaseDelegateAdapter titleAdapter = presenter.initTitle("猜你喜欢");
        mAdapters.add(titleAdapter);
        //初始化list1
        BaseDelegateAdapter girdAdapter = presenter.initList1();
        mAdapters.add(girdAdapter);
    
    
        //初始化标题
        titleAdapter = presenter.initTitle("热门新闻");
        mAdapters.add(titleAdapter);
        //初始化list2
        BaseDelegateAdapter linearAdapter = presenter.initList2();
        mAdapters.add(linearAdapter);
    
        //初始化标题
        titleAdapter = presenter.initTitle("新闻导航");
        mAdapters.add(titleAdapter);
        //初始化list3
        BaseDelegateAdapter girdAdapter3 = presenter.initList3();
        mAdapters.add(girdAdapter3);
    
        //初始化标题
        titleAdapter = presenter.initTitle("为您精选");
        mAdapters.add(titleAdapter);
        //初始化list3
        BaseDelegateAdapter plusAdapter = presenter.initList4();
        mAdapters.add(plusAdapter);
    
        //初始化折叠式指示器控件
        //initSticky();
        //mAdapters.add(stickyAdapter);
    
        //初始化list控件
        titleAdapter = presenter.initTitle("优质新闻");
        mAdapters.add(titleAdapter);
        linearAdapter = presenter.initList5();
        mAdapters.add(linearAdapter);
    
        //设置适配器
        delegateAdapter.setAdapters(mAdapters);
    }
    

    4.相关代码说明

    4.1 VirtualLayoutAdapter
    * 定义:数据适配器。继承自系统的Adaper
    * 作用:创建组件 & 绑定数据到组件
    * 额外:定义了两个接口:
    	* getLayoutHelper():用于返回某个位置组件对应的一个 LayoutHelper
    	* setLayoutHelpers():调用此方法设置整个页面所需要的一系列 LayoutHelper
    * 这两方法的具体实现委托给 VirtualLayoutManager 完成
    
    4.2 VirtualLayoutManager
    * 定义:布局管理器。继承自系统的 LinearLayoutManager
    * 作用:
    
    	* 在 RecyclerView 加载组件或者滑动时调用 VirtualLayoutManager 的 layoutChunk(),返回当前还有哪些空白区域可摆放组件
    	* 管理 LayoutHelper 列表
    * 额外:实现了 VirtualLayoutAdapter 的 getLayoutHelper() & setLayoutHelpers()
    
    4.3 LayoutHelper
    * 定义:LayoutHelper 寻找器
    * 作用:根据页面状态 寻找对应的 LayoutHelper 并返回给 VirtualLayoutManager
    	* VirtualLayoutManager 会持有一个 LayoutHelperFinder
    	* 当 layoutChunck() 被调用时会传入一个位置参数,告诉 VirtualLayoutManager 当前要布局第几个组件
    * VirtualLayoutManager 通知持有的 LayoutHelperFinder 找到传入参数位置对应的 LayoutHelper(每个 LayoutHelper 都会绑定它负责的布局区域的起始位置和结束位置)
    
    4.4 LayoutHelperFinder
    * 定义:布局协助器
    * 作用:负责具体的布局逻辑
    
    4.5 MarginLayoutHelper
    * 定义:继承自 LayoutHelper
    * 作用:扩展 LayoutHelper,提供了布局常用的 内边距padding、外边距margin 的计算功能
    
    4.6 BaseLayoutHelper
    	* 定义:MarginLayoutHelper 的第一层具体实现
    	* 作用:填充 当前LayoutHelper 在屏幕范围内的具体区域 背景色、背景图等逻辑
    
    4.7 子LayoutHelper
    * 定义:MarginLayoutHelper 的第二层具体实现
    * 作用:负责具体的布局逻辑
    	* 每种 子LayoutHelper 负责一种布局逻辑
    	* 重点实现了 beforeLayout()、doLayout()、afterLayout()
    	* 特别是 doLayout():会获取一组件,并对组件进行尺寸计算、界面布局
    	* V - Layout 默认实现了10种默认布局:(对应同名的LayoutHelper)
    * 特别注意:
    	* 每一种 LayoutHelper 负责布局一批组件范围内的组件,不同组件范围内的组件之间,如果类型相同,可以在滑动过程中回收复用。因此回收粒度比较细,且可以跨布局类型复用.
    	* 支持扩展外部:即注册新的 LayoutHelper,实现特殊的布局方式。下面会详细说明
    

    5.相关属性介绍

    5.1 LayoutHelper方法说明
    * 5.1.1 margin, padding
    	* Margin, padding就是外边距、内边距
    	* 它不是整个RecyclerView页面的margin和padding,它是每一块LayoutHelper所负责的区域的margin和padding。
    	* 一个页面里可以有多个LayoutHelper,意味着不同LayoutHelper可以设置不同的margin和padding。
    	* LayoutHelper的margin和padding与页面RecyclerView的margin和padding可以共存。
    	* 目前主要针对非fix类型的LayoutHelper实现了margin和padding,fix类型LayoutHelper内部没有相对位置关系,不处理边距。
    
    * 5.1.2 dividerHeight
    	* LinearLayoutHelper的属性,LinearLayoutHelper是像ListView一样的线性布局,dividerHeight就是每个组件之间的间距。
    
    * 5.1.3 aspectRatio
    	* 为了保证布局过程中视图的高度一致,我们设计了aspectRatio属性,它是宽与高的比例,LayoutHelper里有aspectRatio属性,通过vlayout添加的视图的LayoutParams也有aspectRatio属性,后者的优先级比前者高,但含义不一样。
    		* LayoutHelper定义的aspectRatio,指的是一行视图整体的宽度与高度之比,当然整体的宽度是减去了RecyclerView和对应的LayoutHelper的margin, padding。
    		* 视图的LayoutParams定义的aspectRatio,指的是在LayoutHelper计算出视图宽度之后,用来确定视图高度时使用的,它会覆盖通过LayoutHelper的aspectRatio计算出来的视图高度,因此具备更高优先级。
    
    * 5.1.4 bgColor, bgImg
    	* 背景颜色或者背景图,这其实不是布局属性,但是由于在vlayout对视图进行了直接布局,不同区域的视图的父节点都是RecyclerView,如果想要针对某一块区域单独绘制背景,就很难做到了。vlayout框架对此做了特殊处理,对于非fix、非float类型的LayoutHelper,支持配置背景色或背景图。同样目前主要针对非fix类型的LayoutHelper实现这个特性。
    
    * 5.1.5 weights
    	* ColumnLayoutHelper, GridLayoutHelper的属性,它们都是提供网格状的布局能力,建议使用GridLayoutHelper,它的能力更加强大,参考下文介绍。默认情况下,每个网格中每一列的宽度是一样的,通过weights属性,可以指定让每一列的宽度成比例分配,就像LinearLayout的weight属性一样。 weights属性是一个float数组,每一项代表某一列占父容器宽度的百分比,总和建议是100,否则布局会超出容器宽度;如果布局中有4列,那么weights的长度也应该是4;长度大于4,多出的部分不参与宽度计算;如果小于4,不足的部分默认平分剩余的空间。
    	* 比如,setweights(0.6 , 0.2 , 0.2);那么分配比例是3:1:1
    	
    * 5.1.6 vGap, hGap
    	* GridLayoutHelper与StaggeredGridLayoutHelper都有这两个属性,分别控制视图之间的垂直间距和水平间距。
    	
    * 5.1.7 spanCount, spanSizeLookup
    	* GridLayoutHelper的属性,参考于系统的GridLayoutManager,spanCount表示网格的列数,默认情况下每一个视图都占用一个网格区域,但通过提供自定义的spanSizeLookUp,可以指定某个位置的视图占用多个网格区域
    	
    	
    * 5.1.8 autoExpand
    	* GridLayoutHelper的属性,当一行里视图的个数少于spanCount值的时候,如果autoExpand为true,视图的总宽度会填满可用区域;否则会在屏幕上留空白区域。
    	
    * 5.1.9 lane
    	* StaggeredGridLayoutHelper中有这个属性,与GridLayoutHelper里的spanCount类似,控制瀑布流的列数。
    
    5.2 fix类型的LayoutHelper方法说明
    * 5.2.1 fixAreaAdjuster
    	* fix类型的LayoutHelper,在可能需要设置一个相对父容器四个边的偏移量,比如整个页面里有一个固定的标题栏添加在vlayout容器上,vlayout内部的fix类型视图不希望与外部的标题有所重叠,那么就可以设置一个fixAreaAdjuster来做偏移。
    
    * 5.2.2 alignType, x, y
    	* FixLayoutHelper, ScrollFixLayoutHelper, FloatLayoutHelper的属性,表示吸边时的基准位置,有四个取值,分别是TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT。x和y是相对这四个位置的偏移量,最终的偏移量还要受上述的fixAreaAdjuster影响。
    		* TOP_LEFT:基准位置是左上角,x是视图左边相对父容器的左边距偏移量,y是视图顶边相对父容器的上边距偏移量;
    		* TOP_RIGHT:基准位置是右上角,x是视图右边相对父容器的右边距偏移量,y是视图顶边相对父容器的上边距偏移量;
    		* BOTTOM_LEFT:基准位置是左下角,x是视图左边相对父容器的左边距偏移量,y是视图底边相对父容器的下边距偏移量;
    		* BOTTOM_RIGHT:基准位置是右下角,x是视图右边相对父容器的右边距偏移量,y是视图底边相对父容器的下边距偏移量;
    
    * 5.2.3 showType
    	* ScrollFixLayoutHelper的属性,取值有SHOW_ALWAYS, SHOW_ON_ENTER, SHOW_ON_LEAVE。
    		* SHOW_ALWAYS:与FixLayoutHelper的行为一致,固定在某个位置;
    		* SHOW_ON_ENTER:默认不显示视图,当页面滚动到这个视图的位置的时候,才显示;
    		* SHOW_ON_LEAVE:默认不显示视图,当页面滚出这个视图的位置的时候显示;
    
    * 5.2.4 stickyStart, offset
    	* StickyLayoutHelper的属性,当视图的位置在屏幕范围内时,视图会随页面滚动而滚动;当视图的位置滑出屏幕时,StickyLayoutHelper会将视图固定在顶部(stickyStart = true)或者底部(stickyStart = false),固定的位置支持设置偏移量offset。
    

    6.存在的bug

    7.源码分析

    8.关于其他更多

    8.1 关于本篇博客更新日志
    • v1.0.0 17年9月19日
    • v1.0.1 17年12月11日
    8.2 关于我的博客
    展开全文
  • 使用Alibaba开源库vLayout实现淘宝首页

    千次阅读 2018-01-04 15:18:00
    在研究具体的使用的时候,先看看官方对于vLayout 的介绍和使用方法: vLayout的官方地址: https://github.com/alibaba/vlayout 官方的介绍: 通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;...

    按照自己之前写简书的习惯,先上效果图:(图片素材来自于淘宝手机客户端)
    在这里插入图片描述

    在研究具体的使用的时候,先看看官方对于vLayout 的介绍和使用方法:
    vLayout的官方地址: https://github.com/alibaba/vlayout

    官方的介绍:

    通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比系统自带的LinearLayoutManager、aridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。

    主要功能

    • 默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。
      • LinearLayoutHelper: 线性布局
      • GridLayoutHelper: Grid布局, 支持横向的colspan
      • FixLayoutHelper: 固定布局,始终在屏幕固定位置显示
      • ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等
      • FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置
      • ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值
      • SingleLayoutHelper: 通栏布局,只会显示一个组件View
      • OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素
      • StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底
      • StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度
    • 上述默认实现里可以大致分为两类:一是非fix类型布局,像线性、Grid、栏格等,它们的特点是布局在整个页面流里,随页面滚动而滚动;另一类就是fix类型的布局,它们的子节点往往不随页面滚动而滚动。
    • 所有除布局外的组件复用,VirtualLayout将用来管理大的模块布局组合,扩展了RecyclerView,使得同一RecyclerView内的组件可以复用,减少View的创建和销毁过程。

    如何使用

    版本请参考mvn repository上的最新版本(目前最新版本是1.2.6),最新的 aar 都会发布到 jcenter 和 MavenCentral 上,确保配置了这两个仓库源,然后引入aar依赖:

    compile ('com.alibaba.android:vlayout:1.2.6@aar') {
    	transitive = true
    }
    

    或者maven:
    pom.xml

    <dependency>
      <groupId>com.alibaba.android</groupId>
      <artifactId>vlayout</artifactId>
      <version>1.2.6</version>
      <type>aar</type>
    </dependency>
    

    初始化LayoutManager

    final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    final VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
    
    recyclerView.setLayoutManager(layoutManager);
    

    设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View):

    RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
    recyclerView.setRecycledViewPool(viewPool);
    viewPool.setMaxRecycledViews(0, 10);
    
    

    注意:上述示例代码里只针对type=0的item设置了复用池的大小,如果你的页面有多种type,需要为每一种类型的分别调整复用池大小参数。

    我相信看到这里,还是一脸懵逼,接下来带你一步步的实现上面的复杂效果,我们按照上面的功能顺序一步步的去介绍如何实现?

    1. LinearLayoutHelper 线性布局

    linear.gif

    可以看出和传统的RecycleView的LinearLayoutManager是没有区别的,也就是传统的线性布局管理器。
    由于Adapter和正常的RecycleView的Adapter几乎相似,所以只在LinearLayoutHelper 这个的实现去贴出来,其他的代码已上传Github,查看完整代码。

    核心代码实现:

      DelegateAdapter adapters = new DelegateAdapter(layoutManager, true);
    //Linear 布局
      LinearLayoutHelper linearHelper = new LinearLayoutHelper(10);
      adapters.addAdapter(new LinearAdapter(this,lists, linearHelper));
    

    LinearAdapter的实现:

    public class LinearAdapter extends DelegateAdapter.Adapter<RecyclerView.ViewHolder> {
    
        private Context mContext;
        private LayoutHelper mHelper;
        private List<String> mData;
    
        public LinearAdapter(Context context, List<String> mData, LayoutHelper helper) {
            this.mContext=context;
            this.mData = mData;
            this.mHelper=helper;
        }
    
        @Override
        public LayoutHelper onCreateLayoutHelper() {
            return mHelper;
        }
    
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.item_linear_layout, parent, false);
            return new RecyclerViewItemHolder(view);
        }
    
        @Override
        public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
            RecyclerViewItemHolder recyclerViewHolder = (RecyclerViewItemHolder) holder;
            recyclerViewHolder.tv_name.setText(mData.get(position) );
            recyclerViewHolder.tv_name.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Toast.makeText(mContext, "position:" +position, Toast.LENGTH_SHORT).show();
                }
            });
    
        }
    
        @Override
        public int getItemCount() {
            return mData.size();
        }
    
        /**
         * 正常条目的item的ViewHolder
         */
        private class RecyclerViewItemHolder extends RecyclerView.ViewHolder {
    
            public TextView tv_name;
    
            public RecyclerViewItemHolder(View itemView) {
                super(itemView);
                tv_name = itemView.findViewById(R.id.tv_name);
            }
        }
    }
    

    2. GridLayoutHelper Grid布局, 支持横向的colspan

    grid.gif

    这里只需要看上面的网格布局中的东西,即:
    image.png这部分的内容。当然,这里和使用GridLayoutManager的效果是一样不做过多的解释。相信大家都看得懂。
    核心代码实现:

    //构造中传入相应的列的数量      
      GridLayoutHelper gridHelper = new GridLayoutHelper(5);
            gridHelper.setMarginTop(30);
    //        gridHelper.setWeights(new float[]{20.0f,20.0f,20.0f,20.0f,20.0f});
            //设置垂直方向条目的间隔
            gridHelper.setVGap(5);
            //设置水平方向条目的间隔
            gridHelper.setHGap(5);
            gridHelper.setMarginLeft(30);
            gridHelper.setMarginBottom(30);
            //自动填充满布局,在设置完权重,若没有占满,自动填充满布局
            gridHelper.setAutoExpand(true);
            adapters.addAdapter(new GridHelperAdapter(imgSrc, gridHelper));
    

    3. FixLayoutHelper 固定布局,始终在屏幕固定位置显示

    fix

    在Demo中,最上面的搜索框使用FixLayoutHelper实现的,但是如果只使用FixLayoutHelper的话,这里会将正常的item挡住一部分,所以介绍一种解决方案,即下面提到的ColumnLayoutHelper
    fix.png
    核心代码实现:

    //FixLayoutHelper,构造传入要固定的位置
            FixLayoutHelper fixHelper=new FixLayoutHelper(0,0);
            adapters.addAdapter(new FixLayoutAdapter(this,fixHelper));
    

    4. ScrollFixLayoutHelper固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等

    这个效果类似于FixLayoutHelper ,所以介绍一下相关属性:

    SHOW_ALWAYS:与FixLayoutHelper的行为一致,固定在某个位置;
    SHOW_ON_ENTER:默认不显示视图,当页面滚动到这个视图的位置的时候,才显示;
    SHOW_ON_LEAVE:默认不显示视图,当页面滚出这个视图的位置的时候显示;

    5. FloatLayoutHelper 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置

    悬浮按钮可以任意拖拽,但是会停留在屏幕的边上,暂时还没有找到可以任意拖动的api,后期更新,在使用的过程中如果添加了点击事件,会出现有时候拖动不了的bug,和adapters中初始化的位置和顺序有关系,建议早加入到adapters集合中,优先初始化。

    float.gif

    代码实现:

            //floatLayoutHelper
            FloatLayoutHelper layoutHelper = new FloatLayoutHelper();
            layoutHelper.setAlignType(FixLayoutHelper.BOTTOM_RIGHT);
            layoutHelper.setDefaultLocation(100, 400);
    
            adapters.addAdapter(new FloatLayoutAdapter(this,layoutHelper));
    

    6. ColumnLayoutHelper 栏格布局,都布局在一排,可以配置不同列之间的宽度比值

    Column.png

    代码实现:

    //        //ColumnLayoutHelper
            ColumnLayoutHelper columnLayoutHelper=new ColumnLayoutHelper();
            adapters.addAdapter(new FixLayoutAdapter(this,columnLayoutHelper));
    

    7. SingleLayoutHelper 通栏布局,只会显示一个组件View

    single.gif

    在这个演示图中,我们使用的Banner是使用的SingleLayoutHelper 去实现。

    8. OnePlusNLayoutHelper 一拖N布局,可以配置1-5个子元素

    one3.gif

    这个Helper的实现偶尔会出现图片错位的bug,个人感觉和缓存池有关系(带后期更新)
    代码实现:

            //onePlusNHelper
            OnePlusNLayoutHelper helper = new OnePlusNLayoutHelper();
            helper.setBgColor(R.color.colorPrimary);
            helper.setPadding(5, 5, 5, 5);
    //设置相关的图片展示权重,最好总和加起来是1
            helper.setColWeights(new float[]{50f});
            helper.setMargin(10, 20, 10, 10);
            adapters.addAdapter(new OneToNAdapter(goodSrc.subList(0, 2), helper));
    

    9. StickyLayoutHelper 可以配置吸顶或者吸底

    stick.gif

    即:women这里的悬浮的tablayout使用的是StickyLayoutHelper ,去实现的这种效果。
    代码实现:

            //吸顶的Helper
            StickyLayoutHelper stickyHelper = new StickyLayoutHelper();
            adapters.addAdapter(new StickyLayoutAdapter(stickyHelper));
    

    10. StaggeredGridLayoutHelper 瀑布流布局,可配置间隔高度/宽度

    stag.png
    代码实现:

            //StaggerGridLayoutHelper
            initStagData();
            StaggeredGridLayoutHelper stagHelp=new StaggeredGridLayoutHelper(2);
            stagHelp.setHGap(5);
            stagHelp.setVGap(5);
            adapters.addAdapter(new StaggeredGridLayoutAdapter(this,stagSrc,stagHelp));
    

    好了,到这里vLayout的使用介绍完毕,相信你也有一个大致的了解和认识,代码已上传到Github https://github.com/OnexZgj/VlayoutTest 如果你有相关的问题可以留言,愿与你一起探讨!

    展开全文
  • vlayout的使用

    千次阅读 2017-05-06 14:10:15
    VirtualLayout的使用 阿里 ali

    1.简介

    vlayout全称VirtualLayout,是一个针对RecyclerView的LayoutManager扩展。是阿里最近开源的一个库,主要提供一整套布局方案和布局间的组件复用的问题。

    GitHub地址

    demo示例

    这里写图片描述

    demo地址

    2.优点

    通过定制化的LayoutManager,接管整个RecyclerView的布局逻辑;LayoutManager管理了一系列LayoutHelper,LayoutHelper负责具体布局逻辑实现的地方;每一个LayoutHelper负责页面某一个范围内的组件布局;不同的LayoutHelper可以做不同的布局逻辑,因此可以在一个RecyclerView页面里提供异构的布局结构,这就能比RecylerView自带的LinearLayoutManager、GridLayoutManager、StaggeredGridLayoutManager等提供更加丰富的能力。同时支持扩展LayoutHelper来提供更多的布局能力。

    3.功能(helper类介绍)

    • 默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。

      • LinearLayoutHelper: 线性布局
      • GridLayoutHelper: Grid布局, 支持横向的colspan
      • FixLayoutHelper: 固定布局,始终在屏幕固定位置显示
      • ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等
      • FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置
      • ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值
      • SingleLayoutHelper: 通栏布局,只会显示一个组件View
      • OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素
      • StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底
      • StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度
    • 上述默认实现里可以大致分为两类:一是非fix类型布局,像线性、Grid、栏格等,它们的特点是布局在整个页面流里,随页面滚动而滚动;另一类就是fix类型的布局,它们的子节点往往不随页面滚动而滚动。

    • 所有除布局外的组件复用,VirtualLayout将用来管理大的模块布局组合,扩展了RecyclerView,使得同一RecyclerView内的组件可以复用,减少View的创建和销毁过程。

    4.使用

    01.在项目中的build.gradle配置

    compile ('com.alibaba.android:vlayout:1.0.4@aar') {
        transitive = true
    }

    或者maven:
    pom.xml

    <dependency>
      <groupId>com.alibaba.android</groupId>
      <artifactId>vlayout</artifactId>
      <version>1.0.4</version>
      <type>aar</type>
    </dependency>

    02.初始化VirtualLayoutManager

    VirtualLayoutManager virtualLayoutManager = new VirtualLayoutManager(this);
    mRecylerView.setLayoutManager(virtualLayoutManager);
    

    03.设置缓存view个数(当视图中view的个数很多时,设置合理的缓存大小,防止来回滚动时重新创建 View)

    final RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
    mRecylerView.setRecycledViewPool(viewPool);
    viewPool.setMaxRecycledViews(0, 20);

    04.RecylerView创建适配器,初始化DelegateAdapter

    DelegateAdapter是vlayout封装好的adapter。

    DelegateAdapter delegateAdapter = new DelegateAdapter(virtualLayoutManager, false);
    mRecylerView.setAdapter(delegateAdapter);

    通过调用delegateAdapter.addAdapters或addAdapter中传入DelegateAdapter.Adapter实现类的集合或者单个对象,实现各种不同item布局。

    delegateAdapter.addAdapters(adapters);
    
    delegateAdapter.addAdapter(new MyAdapter(this,new LinearLayoutHelper(,0)));

    05.创建adapter,并继承DelegateAdapter.Adapter

    比继承RecyclerView.Adapter多实现二个方法:onCreateLayoutHelperonBindViewHolderWithOffset

    这里写图片描述

    onCreateLayoutHelper方法通过传给adapter指定的layoutHelper类来设置item的布局样式。

    onBindViewHolderWithOffset方法跟原有onBindViewHolder类似,只是多了一个参数offsetTotal,作用是指当前item在所有adapter item总和个数的位置。

    5.Helper类使用示例

    LinearLayoutHelper使用

    线性布局

    这里写图片描述
    这里写图片描述

    效果演示:

    这里写图片描述

    GridLayoutHelper使用

    这里写图片描述

    效果演示:

    SouthEast

    FixLayoutHelper使用

    固定布局,可让item固定在屏幕某个位置

    这里写图片描述

    效果演示:

    SouthEast

    FloatLayoutHelper使用

    浮动布局,可让item任意拖动

    这里写图片描述

    效果演示

    这里写图片描述

    ColumnLayoutHelper使用

    列表布局,1行可显示多列item。

    这里写图片描述

    效果演示:

    SouthEast

    SingleLayoutHelper使用

    单行布局,可用来单独显示广告轮播图

    这里写图片描述

    效果演示:

    SouthEast

    OnePlusNLayoutHelper使用

    一拖N布局(N最大为4),即OnePlusNLayoutHelper最多只能有5个item。

    这里写图片描述

    效果演示:

    SouthEast

    StickyLayoutHelper使用

    吸附布局,可将item吸附在顶部 以及 底部,并进行偏移。

    这里写图片描述

    效果演示:

    这里写图片描述

    StaggeredGridLayoutHelper使用

    瀑布流布局

    这里写图片描述

    效果演示

    这里写图片描述

    6.helper类内部方法说明

    setBgColor:设置item背景颜色

    setMargin:设置item外间距

    setPadding:设置item内间距

    setAspectRatio:设置item宽高比例。

    setDeviderHeight:设置间距(LinearLayoutHelper拥有方法)

    代码演示:

    LinearLayoutHelper layoutHelper2 = new LinearLayoutHelper();
    layoutHelper2.setAspectRatio(4.0f);
    layoutHelper2.setDividerHeight(10);
    layoutHelper2.setMargin(10, 30, 10, 10);//左 上 右 下
    layoutHelper2.setPadding(10, 30, 10, 10);//左 上 右 下
    layoutHelper2.setBgColor(0xFFF5A623);

    效果演示:

    SouthEast

    setGap:设置item与item之间的距离((GridLayoutHelper和StaggeredGridLayoutHelper拥有方法)

    setHGap: 设置水平方向item与item之间的距离(GridLayoutHelper和StaggeredGridLayoutHelper拥有方法)

    setVGap:设置垂直方向item与item之间的距离(GridLayoutHelper和StaggeredGridLayoutHelper拥有方法)

    代码示例:

    GridLayoutHelper helper = new GridLayoutHelper(3);
    helper.setMargin(7, 7, 7, 7);
    helper.setPadding(10, 10, 10, 10);
    helper.setBgColor(0xff87e543);
    helper.setGap(3);
    helper.setHGap(3);
    helper.setVGap(3);
    helper.setAutoExpand(true);
    MyAdapter myAdapter = new MyAdapter(this, helper, 10);
    adapters.add(myAdapter);

    效果演示:

    SouthEast

    setAlignType: 设置摆放位置(FloatLayoutHelper、FixLayoutHelper、ScrollFixLayoutHelper拥有方法)

    代码示例:

    layoutHelper.setAlignType(FixLayoutHelper.BOTTOM_RIGHT); //右下
    layoutHelper.setAlignType(FixLayoutHelper.BOTTOM_LEFT);  //左下
    layoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);    //左上
    layoutHelper.setAlignType(FixLayoutHelper.TOP_RIGHT);   //右上

    setWeights:设置每个item的比重,权重属性(ColumLayoutHelper拥有方法)

    setColWeights和setRowWeight: 设置行跟内每个item的比重 ,权重属性(OnePlusNLayoutHelper拥有方法)

    总结

    相比RecylerView的自带的LayoutManager强大很多。在开发中可以灵活使用多种Helper,拓展布局的多样性。

    展开全文
  • vlayout的简单介绍

    2019-02-15 11:26:24
    alibaba/vlayout github 中文文档 依赖 compile ('com.alibaba.android:vlayout:1.2.8@aar') { transitive = true } 初始化LayoutManager final RecyclerView recyclerView = (RecyclerView) findViewById...

    参考:

    alibaba/vlayout github 中文文档

    Android开源库V - Layout:淘宝、天猫都在用的UI框架,赶紧用起来吧!

    android VLayout 全面解析

    使用Alibaba开源库vLayout实现淘宝首页

    依赖

    compile ('com.alibaba.android:vlayout:1.2.8@aar') {
    	transitive = true
    }
    

    初始化LayoutManager

    final RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    final VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
    
    recyclerView.setLayoutManager(layoutManager);
    

    在这里插入图片描述

    设置回收复用池大小

    如果一屏内相同类型的 View 个数比较多,需要设置一个合适的大小,防止来回滚动时重新创建 View:

    RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
    
    recyclerView.setRecycledViewPool(viewPool);
    
    viewPool.setMaxRecycledViews(0, 10);
    

    注意:上述示例代码里只针对type=0的item设置了复用池的大小,如果你的页面有多种type,需要为每一种类型的分别调整复用池大小参数。

    加载数据

    加载数据时有两种方式 : DelegateAdapter 和 VirtualLayoutAdapter

    在这里插入图片描述

    使用 DelegateAdapter, 可以像平常一样写继承自DelegateAdapter.Adapter的Adapter, 只比之前的Adapter需要多重载onCreateLayoutHelper方法。 其他的和默认Adapter一样。

    DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, hasConsistItemType);
    recycler.setAdapter(delegateAdapter);
    
    // 之后可以通过 setAdapters 或 addAdapter方法添加DelegateAdapter.Adapter
    
    delegateAdapter.setAdapters(adapters);
    
    // or
    CustomAdapter adapter = new CustomAdapter(data, new GridLayoutHelper());
    delegateAdapter.addAdapter(adapter);
    
    // 如果数据有变化,调用自定义 adapter 的 notifyDataSetChanged()
    adapter.notifyDataSetChanged();
    

    注意:

    当hasConsistItemType=true的时候,不论是不是属于同一个子adapter,相同类型的item都能复用。表示它们共享一个类型。

    当hasConsistItemType=false的时候,不同子adapter之间的类型不共享

    另一种是当业务有自定义的复杂需求的时候, 可以继承自VirtualLayoutAdapter, 实现自己的Adapter

    public class MyAdapter extends VirtualLayoutAdapter {
       ......
    }
    
    MyAdapter myAdapter = new MyAdapter(layoutManager);
    
    //构造 layoutHelper 列表
    List<LayoutHelper> helpers = new LinkedList<>();
    GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(4);
    gridLayoutHelper.setItemCount(25);
    helpers.add(gridLayoutHelper);
    
    GridLayoutHelper gridLayoutHelper2 = new GridLayoutHelper(2);
    gridLayoutHelper2.setItemCount(25);
    helpers.add(gridLayoutHelper2);
    
    //将 layoutHelper 列表传递给 adapter
    myAdapter.setLayoutHelpers(helpers);
    
    //将 adapter 设置给 recyclerView
    recycler.setAdapter(myAdapter);
    

    在这种情况下,需要使用者注意在当LayoutHelpers的结构或者数据数量等会影响到布局的元素变化时,需要主动调用setLayoutHelpers去更新布局模式。

    layouthelper分类及关系

    默认通用布局实现,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等。

    • LinearLayoutHelper: 线性布局
    • GridLayoutHelper: Grid布局, 支持横向的colspan
    • FixLayoutHelper: 固定布局,始终在屏幕固定位置显示
    • ScrollFixLayoutHelper: 固定布局,但之后当页面滑动到该图片区域才显示, 可以用来做返回顶部或其他书签等
    • FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置
    • ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值
    • SingleLayoutHelper: 通栏布局,只会显示一个组件View
    • OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素
    • StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底
    • StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度

    上述默认实现里可以大致分为两类:
    一是非fix类型布局,像线性、Grid、栏格等,它们的特点是布局在整个页面流里,随页面滚动而滚动;
    另一类就是fix类型的布局,它们的子节点往往不随页面滚动而滚动。

    在这里插入图片描述

    混淆

    -keepattributes InnerClasses
    -keep class com.alibaba.android.vlayout.ExposeLinearLayoutManagerEx { *; }
    -keep class android.support.v7.widget.RecyclerView$LayoutParams { *; }
    -keep class android.support.v7.widget.RecyclerView$ViewHolder { *; }
    -keep class android.support.v7.widget.ChildHelper { *; }
    -keep class android.support.v7.widget.ChildHelper$Bucket { *; }
    -keep class android.support.v7.widget.RecyclerView$LayoutManager { *; }
    
    展开全文
  • 项目接入实现复杂布局的vlayout

    千次阅读 2018-03-08 09:40:25
    前言V- Layout 是阿里出品的基础 UI 框架,用于...Github - alibaba - vlayout Github在五一假期我对V- Layout进行了详细分析,我将献上一份 V- Layout的使用攻略 &amp; 源码分析,希望你们会喜欢。阅读本文前...
  • 阿里Ui框架Vlayout使用详细介绍

    千次阅读 2018-05-03 23:34:48
    转载于:www.jcodecraeer.com/a/anzhuokaifa/2018/0108/9088.htmlVlayout使用详细介绍目录介绍1.Vlayout简单介绍2.主要功能介绍2.1 主要功能的思维导图2.2 主要功能说明.使用方法与案例3.1 初始化3.2 设置回收复用池...
  • android VLayout 全面解析

    万次阅读 热门讨论 2017-03-28 13:18:51
    概述前不久,阿里新开源了2个东西,Atlas和vlayout。今天我来介绍下vlayout的使用。在介绍前,先抱怨两句,阿里放开源出来,感觉就是让我们这群人给他们找bug~~我曾遇到一个奇怪的问题,然后一直以为自己写的有问题...
  • vlayout原理剖析

    2019-04-29 11:40:35
    vlayout是阿里的一个开源ui框架,是一个实现多样的item的列表的神器,相信大多数开发者对于vlayout内部的实现原理不太了解。本篇文章就和大家一起探讨下valyout的内部原理: 用过vlayout的同学都知道他的主要几个...
  • vlayout的初始尝试使用

    2019-10-14 14:37:04
    对于这种不规则的列表展示方式,vlayout就是最好的选择。由于初始使用这个,需要先做技术预研,所以就写了个简单的demo体验效果。 效果如下: (1)当item个数为奇数的时候,展示效果如下: (2)当item个数为偶数...
  • vlayout

    2017-08-23 13:53:39
    天猫淘宝在用的UI框架 ... 如下图是过度绘制的颜色分类:其中蓝色、淡绿、淡红、深红代表了4种不同程度的overdraw情况,我们的目标就是尽量减少红色的overdraw,看到更多...如下是用vlayout写成的demo的过度绘制情况
  • vlayout是阿里开源的一个用来辅助RecyclerView的LayoutManager扩展库,通过使用里面的LayoutHelper,我们可以轻松的使用一些比较复杂的布局,如:线性布局、Grid布局、固定布局、浮动布局、栏格布局、通栏布局、一拖...
  • 阿里VLayout学习笔记(Kotlin) VLayout中LayoutHelper分类(辅助Adapter实现RecyclerView的Item各种类型的布局方式) LinearLayoutHelper: 线性布局 GridLayoutHelper: Grid布局, 支持横向的colspan ...
  • vlayout 实现仿各大商场demo, 添加footer监听支持下拉加载更多。
  • vLayout使用注意事项

    千次阅读 2018-08-23 15:19:02
    vlayout的引用到项目中需要配置gradle: compile 'com.alibaba.android:vlayout:1.2.14@aar' 引用到代码中可以如下使用: //设置回收复用池大小,(如果一屏内相同类型的 View 个数比较多,需要设置一个合适的...
  • Android UI 阿里VLayout使用 开源地址(2017.03开源):https://github.com/alibaba/vlayout/ VirtualLayout是一个针对RecyclerView的LayoutManager扩展, 主要提供一整套布局方案和布局间的组件复用 可以很方便的利用...
  • vlayout使用解析

    千次阅读 2017-05-06 14:20:10
    vlayout使用解析
  • 淘宝首页是从上到下是各种不同的样式,最上面是搜索,其次是一个轮播图,再下来是10个圆角的菜单,等等,我们可以采用一个recyclerView实现,但是实现起来的复杂程度是比较高的,如果使用阿里开源的VLayout控件,...
  • Tangram 的基础 —— vlayout(Android)

    千次阅读 2017-03-04 08:54:51
    vlayout 是手机天猫 Android 版内广泛使用的一个基础 UI 框架项目 提供了一个用于RecyclerView的自定义的LayoutManger,可以实现不同布局格式的混排,目标是支撑客户端native页面的快速开发。它也是Tangram 框架的...
  • VLayout 概念 定义: VLayout全程VirtuaLayout,它是一个针对RecyclerView的LayoutManager扩展,主要提供一整套布局方案 和布局间的组件复用的问题。由阿里团队开发,已经运用在手机淘宝项目上。2017年3月份开源...
  • VLayout实例

    2017-03-28 11:37:18
    这是关于阿狸开源项目vlayout的介绍
1 2 3 4 5 ... 20
收藏数 1,666
精华内容 666
关键字:

vlayout