Vlayout使用详细介绍

简介: Vlayout使用详细介绍 目录介绍 1.Vlayout简单介绍 2.主要功能介绍 2.1 主要功能的思维导图 2.2 主要功能说明 .使用方法与案例 3.1 初始化 3.2 设置回收复用池 3.3 设置RecycleView适配器 3.

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 关于我的博客

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日
目录
相关文章
|
缓存 Android开发
Android RecyclerView 实现瀑布流
Android RecyclerView 实现瀑布流
|
7月前
|
人工智能 数据挖掘 程序员
深度解析|非技术人的AI Agent黄金职业路线:做智能时代的“超级连接者”
本文打破“只有程序员才能参与AI革命”的迷思,专为运营、市场、销售、产品等非技术人才设计,揭示如何凭借业务理解与软技能,转型为AI Agent生态中的“赋能者”与“运营者”,实现职业价值跃升。(239字)
862 1
|
算法 程序员 应用服务中间件
推荐一款基于docker部署的个人免费笔记工具wiznote
推荐一款基于docker部署的个人免费笔记工具wiznote
推荐一款基于docker部署的个人免费笔记工具wiznote
|
3月前
|
人工智能 自然语言处理 算法
阿里云百炼Qwen 3.7 Plus与Max实测全解:性价比与多模态能力、成本深度对比
2026年,阿里云百炼平台推出的Qwen 3.7系列成为企业与开发者落地AI应用的核心选择,其中Qwen 3.7 Max与Plus作为两大旗舰版本,定位差异显著:Max是纯文本推理旗舰,专注高强度智能体与复杂逻辑任务;Plus则是多模态全能版,在保留强大文本能力的同时,补齐图像、视频理解能力,且价格大幅降低。本文基于2026年最新实测数据,从核心参数、文本能力、多模态能力、智能体表现、性价比与场景选型六大维度,全面解析两款模型的差异,为用户提供精准选型参考。
2052 0
|
Android开发
IDEA编译gradle提示This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 2020.3.1 or newer.
IDEA编译gradle提示This version of the Android Support plugin for IntelliJ IDEA (or Android Studio) cannot open this project, please retry with version 2020.3.1 or newer.
1710 1
|
7月前
四大核心能力重磅发布!通义灵码 0.3.0 全新升级,2月6日直播间见!
"四大核心能力重磅发布!通义灵码 0.3.0 全新升级,2月6日直播间见!
|
人工智能 Serverless 数据处理
AI练习场|如何从多模态文件中自动提取有效信息?
本文介绍了利用AI技术进行多模态文件信息抽取的实战教程,涵盖从文档、图像、音视频等多种数据中自动提取关键信息的技术方案。通过阿里云百炼模型与函数计算服务,实现高效数据处理,适用于信息提取、图片分类、音视频分析等场景,提升数据处理效率与准确性。
AI练习场|如何从多模态文件中自动提取有效信息?
|
Linux PHP
Linux CentOS 宝塔 Suhosin禁用php5.6版本eval函数详细图文教程
【8月更文挑战第27天】本文介绍两种禁用PHP执行的方法:使用`PHP_diseval_extension`禁用和通过`suhosin`禁用。由于`suhosin`不支持PHP8,仅适用于PHP7及以下版本,若服务器安装了PHP5.6,则需对应安装`suhosin-0.9.38`版本。文章提供了详细的安装步骤,并强调了宝塔环境下与普通环境下的PHP路径差异。安装完成后,在`php.ini`中添加`suhosin.so`扩展并设置`executor.disable_eval = on`以禁用执行功能。最后通过测试代码验证是否成功禁用,并重启`php-fpm`服务生效。
665 2
|
XML Android开发 UED
💥Android UI设计新风尚!掌握Material Design精髓,让你的界面颜值爆表!🎨
【7月更文挑战第28天】随着移动应用市场的发展,用户对界面设计的要求不断提高。Material Design是由Google推出的设计语言,强调真实感、统一性和创新性,通过模拟纸张和墨水的物理属性创造沉浸式体验。它注重色彩、排版、图标和布局的一致性,确保跨设备的统一视觉风格。Android Studio提供了丰富的Material Design组件库,如按钮、卡片等,易于使用且美观。
849 1

热门文章

最新文章