阿里布局

还需整理

1. 线性布局(LinearLayoutHelper)

/** 设置线性布局 */

 LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();

// 创建对应的LayoutHelper对象 // 所有布局的公共属性(属性会在下面详细说明) linearLayoutHelper.setItemCount(4);

// 设置布局里Item个数

 linearLayoutHelper.setPadding(10,10,10,10);

// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离 

linearLayoutHelper.setMargin(10,10,10,10);

// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离 

linearLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色 

linearLayoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比

 // linearLayoutHelper特有属性 

linearLayoutHelper.setDividerHeight(1); // 设置每行Item的距离

1. 所有布局的共有属性说明:

a. setItemCount属性

  • 作用:设置整个布局里的Item数量 

如设置的Item总数如与Adapter的getItemCount()方法返回的数量不同,会取决于后者

b. Adding & Margin属性

定义:都是边距的含义,但二者边距的定义不同:

Padding:是 LayoutHelper 的子元素相对 LayoutHelper 边缘的距离;

Margin:是 LayoutHelper 边缘相对父控件(即RecyclerView)的距离。

// 具体使用 linearLayoutHelper.setPadding(10,10,10,10);

// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离 

linearLayoutHelper.setMargin(10,10,10,10);

// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

c. bgColor属性

  • 作用:设置布局背景颜色

// 具体使用 linearLayoutHelper.setBgColor(Color.YELLOW);

d. aspectRatio属性

  • 作用:设置布局内每行布局的宽与高的比。
  • 具体使用

((VirutalLayoutManager.LayoutParams) layoutParams).mAspectRatio

// 视图的LayoutParams定义的aspectRatio 

// 在LayoutHelper计算出视图宽度之后,用来确定视图高度时使用的,它会覆盖通过LayoutHelper的aspectRatio计算出来的视图高度,因此具备更高优先级。 

// 具体使用 

linearLayoutHelper.setAspectRatio(6);

2. LinearLayoutHelper布局的特有属性说明

a. dividerHeight属性

  • 作用:设置每行Item之间的距离 

设置的间隔会与RecyclerView的addItemDecoration()添加的间隔叠加

  • // 具体使用 linearLayoutHelper.setDividerHeight(1);
  • 布局说明:布局里的Item以网格的形式进行排列
  • 具体使用

2. 网格布局(GridLayout)

        /** 设置Grid布局 */

        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(3);

        // 在构造函数设置每行的网格个数

        // 公共属性

        gridLayoutHelper.setItemCount(6);// 设置布局里Item个数

        gridLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        gridLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        gridLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        gridLayoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比

        // gridLayoutHelper特有属性(下面会详细说明)

        gridLayoutHelper.setWeights(new float[]{40, 30, 30});//设置每行中 每个网格宽度 占 每行总宽度 的比例

        gridLayoutHelper.setVGap(20);// 控制子元素之间的垂直间距

        gridLayoutHelper.setHGap(20);// 控制子元素之间的水平间距

        gridLayoutHelper.setAutoExpand(false);//是否自动填充空白区域

        gridLayoutHelper.setSpanCount(3);// 设置每行多少个网格

        // 通过自定义SpanSizeLookup来控制某个Item的占网格个数

        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {

            @Override

            public int getSpanSize(int position) {

                if (position > 7 ) {

                    return 3;

                    // 第7个位置后,每个Item占3个网格

                }else {

                    return 2;

                    // 第7个位置前,每个Item占2个网格

                }

            }

        });

1.GridLayoutHelper布局的特有属性说明

a. weights属性

  • 作用:设置每行中每个网格宽度占每行总宽度的比例 
  1. 默认情况下,每行中每个网格中的宽度相等 
  2. weights属性是一个float数组,每一项代表当个网格占每行总宽度的百分比;总和是100,否则布局会超出容器宽度; 
  3. 如果布局中有4列,那么weights的长度也应该是4;长度大于4,多出的部分不参与宽度计算;如果小于4,不足的部分默认平分剩余的空间。

// 具体使用 gridLayoutHelper.setWeights(new float[]{40, 30, 30});

b. vGap、hGap属性

  • 作用:分别控制子元素之间的垂直间距 水平间距。

// 具体使用 gridLayoutHelper.setVGap(20);// 控制子元素之间的垂直间距 gridLayoutHelper.setHGap(20);// 控制子元素之间的水平间距

c. spanCount、spanSizeLookup属性

  • 作用: 

spanCount:设置每行多少个网格

spanSizeLookup:设置每个 Item占用多少个网格(默认= 1)

// 具体使用 gridLayoutHelper.setSpanCount(5);// 设置每行多少个网格 // 通过自定义SpanSizeLookup来控制某个Item的占网格个数 gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position > 7 ) { return 3; // 第7个位置后,每个Item占3个网格 }else { return 2; // 第7个位置前,每个Item占2个网格 } } });

d. autoExpand属性

  • 作用:当一行里item的个数 < (每行网格列数 - spanCount值/ 每个Item占有2个网格-setSpanSizeLookup )时,是否自动填满空白区域 
  1. autoExpand=true,那么视图的总宽度会填满可用区域; 
  2. 否则会在屏幕上留空白区域。

// 具体使用 gridLayoutHelper.setAutoExpand(false);

3. 固定布局(FixLayoutHelper)

  • 布局说明:布局里的Item 固定位置 

固定在屏幕某个位置,且不可拖拽 & 不随页面滚动而滚动

  • 具体使用

/** 设置固定布局 */

        FixLayoutHelper fixLayoutHelper = new FixLayoutHelper(FixLayoutHelper.TOP_LEFT,40,100);

        // 参数说明:

        // 参数1:设置吸边时的基准位置(alignType) - 有四个取值:TOP_LEFT(默认), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT

        // 参数2:基准位置的偏移量x

        // 参数3:基准位置的偏移量y

        // 公共属性

        fixLayoutHelper.setItemCount(1);// 设置布局里Item个数

        fixLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        fixLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        fixLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        fixLayoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比

        // fixLayoutHelper特有属性

        fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// 设置吸边时的基准位置(alignType)

        fixLayoutHelper.setX(30);// 设置基准位置的横向偏移量X

        fixLayoutHelper.setY(50);// 设置基准位置的纵向偏移量Y

1.FixLayoutHelper特有属性说明

a. AlignType、x、y属性

  • 作用: 
  1. alignType:吸边基准类型 

共有4个取值:TOP_LEFT(默认), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,具体请看下面示意图

  1. x:基准位置的横向偏移量
  2. y:基准位置的纵向偏移量
  • 作用对象:FixLayoutHelper, ScrollFixLayoutHelper, FloatLayoutHelper的属性

// 具体使用 fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT); fixLayoutHelper.setX(30); fixLayoutHelper.setY(50);

4. 可选显示的固定布局(ScrollFixLayoutHelper)

  • 布局说明:布局里的Item 固定位置 

固定在屏幕某个位置,且不可拖拽 & 不随页面滚动而滚动(继承自固定布局(FixLayoutHelper)) 

唯一不同的是,可以自由设置该Item什么时候显示(到顶部显示 / 到底部显示),可如下图:(左上角) 

需求场景:到页面底部显示”一键到顶部“的按钮功能

/** 设置可选固定布局 */

 ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(ScrollFixLayoutHelper.TOP_RIGHT,0,0);

 // 参数说明:

 // 参数1:设置吸边时的基准位置(alignType) - 有四个取值:TOP_LEFT(默认), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT 

// 参数2:基准位置的偏移量x

// 参数3:基准位置的偏移量y 

// 公共属性 

scrollFixLayoutHelper.setItemCount(1);

// 设置布局里Item个数

// 从设置Item数目的源码可以看出,一个FixLayoutHelper只能设置一个 scrollFixLayoutHelper.setPadding(20, 20, 20, 20);

// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离 

scrollFixLayoutHelper.setMargin(20, 20, 20, 20);

// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离 

scrollFixLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色 

scrollFixLayoutHelper.setAspectRatio(6);

// 设置设置布局内每行布局的宽与高的比 

// fixLayoutHelper特有属性 

scrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);

// 设置吸边时的基准位置(alignType) 

scrollFixLayoutHelper.setX(30);// 设置基准位置的横向偏移量X 

scrollFixLayoutHelper.setY(50);// 设置基准位置的纵向偏移量Y 

scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);

// 设置Item的显示模式

1.ScrollFixLayoutHelper特有属性说明

a. AlignType、x、y属性

  • 作用: 
  1. alignType:吸边基准类型 

共有4个取值:TOP_LEFT(默认), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,具体请看下面示意图

  1. x:基准位置的横向偏移量
  2. y:基准位置的纵向偏移量

// 具体使用 ScrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT); ScrollFixLayoutHelper.setX(30); ScrollFixLayoutHelper.setY(50);

b. ShowType属性

作用:设置Item的显示模式

共有三种显示模式

SHOW_ALWAYS:永远显示(即效果同固定布局)

SHOW_ON_ENTER:默认不显示视图,当页面滚动到该视图位置时才显示;

SHOW_ON_LEAVE:默认不显示视图,当页面滚出该视图位置时才显示

// 具体使用

scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);

5. 浮动布局(FloatLayoutHelper)

  • 布局说明:布局里的Item只有一个 
  1. 可随意拖动,但最终会被吸边到两侧 
  2. 不随页面滚动而移动
  • 具体使用

/** 设置浮动布局 */

        FloatLayoutHelper floatLayoutHelper = new FloatLayoutHelper();

        // 创建FloatLayoutHelper对象

        // 公共属性

        floatLayoutHelper.setItemCount(1);// 设置布局里Item个数

        // 从设置Item数目的源码可以看出,一个FixLayoutHelper只能设置一个        floatLayoutHelper.setPadding(20, 20, 20, 20);

// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        floatLayoutHelper.setMargin(20, 20, 20, 20);

// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        floatLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

      floatLayoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比

        // floatLayoutHelper特有属性

        floatLayoutHelper.setDefaultLocation(300,300);// 设置布局里Item的初始位置

6. 栏格布局(ColumnLayoutHelper)

  • 布局说明:该布局只设有一栏(该栏设置多个Item) 

可理解为只有一行的线性布局

/** 设置栏格布局 */

 ColumnLayoutHelper columnLayoutHelper = new ColumnLayoutHelper(); // 创建对象 

// 公共属性

 columnLayoutHelper.setItemCount(3);// 设置布局里Item个数

 columnLayoutHelper.setPadding(20, 20, 20, 20);

// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离 

columnLayoutHelper.setMargin(20, 20, 20, 20);

// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离 

columnLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色 

columnLayoutHelper.setAspectRatio(6);

// 设置设置布局内每行布局的宽与高的比

// columnLayoutHelper特有属性

 columnLayoutHelper.setWeights(new float[]{30, 40, 30});

// 设置该行每个Item占该行总宽度的比例 

// 同上面Weigths属性讲解

7. 通栏布局(SingleLayoutHelper)

  • 布局说明:布局只有一栏,该栏只有一个Item
  • 具体使用

/** 设置通栏布局 */

        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();

        // 公共属性

        singleLayoutHelper.setItemCount(3);// 设置布局里Item个数

        singleLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        singleLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        singleLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        singleLayoutHelper.setAspectRatio(6);// 设置设置布局内每行布局的宽与高的比

8. 一拖N布局 (OnePlusNLayoutHelper)

  • 布局说明:将布局分为不同比例,最多是1拖4

 

  • 具体使用

/** 设置1拖N布局 */

        OnePlusNLayoutHelper onePlusNLayoutHelper = new OnePlusNLayoutHelper(5);

        // 在构造函数里传入显示的Item数

        // 最多是1拖4,即5个

        // 公共属性

        onePlusNLayoutHelper.setItemCount(3);// 设置布局里Item个数

        onePlusNLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        onePlusNLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        onePlusNLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        onePlusNLayoutHelper.setAspectRatio(3);// 设置设置布局内每行布局的宽与高的比

9. 吸边布局(StickyLayoutHelper)

布局说明:布局只有一个Item,显示逻辑如下:

  1. 当它包含的组件处于屏幕可见范围内时,像正常的组件一样随页面滚动而滚动
  2. 当组件将要被滑出屏幕返回的时候,可以吸到屏幕的顶部或者底部,实现一种吸住的效果
  • 具体使用

        /** 设置吸边布局 */

        StickyLayoutHelper stickyLayoutHelper = new StickyLayoutHelper();

        // 公共属性

        stickyLayoutHelper.setItemCount(3);// 设置布局里Item个数

        stickyLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        stickyLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        stickyLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        stickyLayoutHelper.setAspectRatio(3);// 设置设置布局内每行布局的宽与高的比

        // 特有属性

        stickyLayoutHelper.setStickyStart(true);

        // true = 组件吸在顶部

        // false = 组件吸在底部

 

        stickyLayoutHelper.setOffset(100);// 设置吸边位置的偏移量

        Adapter_StickyLayout = new MyAdapter(this, stickyLayoutHelper,1, listItem) {

            // 设置需要展示的数据总数,此处设置是1

            // 为了展示效果,通过重写onBindViewHolder()将布局的第一个数据设置为Stick

            @Override

            public void onBindViewHolder(MainViewHolder holder, int position) {

                super.onBindViewHolder(holder, position);

                if (position == 0) {

                    holder.Text.setText("Stick");

                }

            }

        };

        adapters.add(Adapter_StickyLayout) ;

        // 将当前的Adapter加入到Adapter列表里

1.stickyStart、 offset属性说明

作用:

stickyStart:设置吸边位置

当视图的位置在屏幕范围内时,视图会随页面滚动而滚动;当视图的位置滑出屏幕时,StickyLayoutHelper会将视图固定在顶部(stickyStart = true)或 底部(stickyStart = false)

offset:设置吸边的偏移量

具体使用

// 接口示意

        public void setStickyStart(boolean stickyStart)

        public void setOffset(int offset)

// 具体使用

        stickyLayoutHelper.setStickyStart(true);

        // true = 组件吸在顶部

        // false = 组件吸在底部

        stickyLayoutHelper.setOffset(100);// 设置吸边位置的偏移量

10. 瀑布流布局(StaggeredGridLayoutHelper)

  • 布局说明:以网格的形式进行布局。与网格布局类似,区别在于: 
  • 网格布局每栏的Item高度是相等的;
  • 瀑布流布局每栏的Item高度是可以不相等的。
  • 具体使用

 

        /** 设置瀑布流布局 */

        StaggeredGridLayoutHelper staggeredGridLayoutHelper = new StaggeredGridLayoutHelper();

        // 创建对象

 

        // 公有属性

        staggeredGridLayoutHelper.setItemCount(20);// 设置布局里Item个数

        staggeredGridLayoutHelper.setPadding(20, 20, 20, 20);// 设置LayoutHelper的子元素相对LayoutHelper边缘的距离

        staggeredGridLayoutHelper.setMargin(20, 20, 20, 20);// 设置LayoutHelper边缘相对父控件(即RecyclerView)的距离

        staggeredGridLayoutHelper.setBgColor(Color.GRAY);// 设置背景颜色

        staggeredGridLayoutHelper.setAspectRatio(3);// 设置设置布局内每行布局的宽与高的比

 

        // 特有属性

        staggeredGridLayoutHelper.setLane(3);// 设置控制瀑布流每行的Item数

        staggeredGridLayoutHelper.setHGap(20);// 设置子元素之间的水平间距

        staggeredGridLayoutHelper.setVGap(15);// 设置子元素之间的垂直间距

 

1.自定义布局(即自定义LayoutHelper)

除了使用系统提供的默认布局 LayoutHelper,开发者还可以通过自定义LayoutHelper从而实现自定义布局样式。有三种方式:

继承BaseLayoutHelper:从上而下排列的顺序 & 内部 View可以按行回收的布局;主要实现layoutViews()computeAlignOffset()等方法

LinearLayoutHelperGridLayoutHelper都是采用该方法实现

继承AbstractFullFillLayoutHelper:有些布局内部的 View 并不是从上至下排列的顺序(即 Adatper 里的数据顺序和物理视图顺序不一致,那么可能就不能按数据顺序布局和回收),需要一次性布局 
& 回收。主要实现layoutViews()等方法

OnePlusNLayoutHelper采用该方法实现

继承FixAreaLayoutHelperfix 类型布局,子节点不随页面滚动而滚动。主要实现layoutViews()beforeLayout()afterLayout()等方法

FixLayoutHelper采用该方法实现

 

步骤5:将生成的LayoutHelper 交给Adapter,并绑定到RecyclerView 对象

此处的做法会因步骤3中Adapter的设置而有所不同

<-- 方式1Adapter继承 自 DelegateAdapter -->

// 步骤1:设置Adapter列表(同时也是设置LayoutHelper列表)

        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

// 步骤2:创建自定义的Adapter对象 & 绑定数据 & 绑定上述对应的LayoutHelper// 绑定你需要展示的布局LayoutHelper即可,此处仅展示两个。

        MyAdapter Adapter_linearLayout    = new MyAdapter(this, linearLayoutHelper,ListItem);// ListItem是需要绑定的数据(其实取决于你的Adapter如何定义)

 

        MyAdapter Adapter_gridLayoutHelper    = new MyAdapter(this, gridLayoutHelper,ListItem);

// 步骤3:将创建的Adapter对象放入到DelegateAdapter.Adapter列表里

        adapters.addAdapter_linearLayout ) ;

        adapters.addAdapter_gridLayoutHelper ) ;

// 步骤4:创建DelegateAdapter对象 & 将layoutManager绑定到DelegateAdapter

DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager);

// 步骤5:将DelegateAdapter.Adapter列表绑定到DelegateAdapter

 delegateAdapter.setAdapters(adapters);

// 步骤6:将delegateAdapter绑定到recyclerView

recyclerView.setAdapter(delegateAdapter);

 

 

 

<-- 方式2Adapter继承 自 VirtualLayoutAdapter -->

// 步骤1:设置LayoutHelper列表

        List<LayoutHelper> helpers = new LinkedList<>();

// 步骤2:绑定上述对应的LayoutHelper

helpers.addAdapter_linearLayout );

helpers.addAdapter_gridLayoutHelper ) ;

// 步骤3:创建自定义的MyAdapter对象 & 绑定layoutManager

MyAdapter myAdapter = new MyAdapter(layoutManager);

// 步骤4:将 layoutHelper 列表传递给 adapter

myAdapter.setLayoutHelpers(helpers);

// 步骤5:将adapter绑定到recyclerView

recycler.setAdapter(myAdapter);

至此,使用过程讲解完毕。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

最近淘宝出了vlayout,刚开始看淘宝的文档的时候还是有点懵,后来自己也总结规划了一下,写了一个比较好看的demo,顺便在这里总结一下。

 

VLayout是什么,说白了就是用一个原生RecycelerView加上VLayout来实现在一个页面上比较复杂的布局并且有一个比较好的复用,在RecyclerView里同时有GridLayout布局,瀑布流布局,浮动布局等VLayout提供的九大布局,这也是淘宝客户端首页加载不同布局的方法。

 

好了,简单介绍到这里,首先我们先导入VLayout:

 

compile ('com.alibaba.android:vlayout:版本@aar') {

 

    transitive = true

 

}

 

具体的版本请看githubVLayout给出的版本号。现在最新是1.0.6

 

接着我们就可以开始引用VLayout,VLayout的通用代码如下:

 

VirtualLayoutManager manager = new VirtualLayoutManager(this);

 

recyclerview.setLayoutManager(manager);

 

DelegateAdapter adapter =new DelegateAdapter(manager, true);

 

 

 

  • 其中VirtualLayoutManager它继承自LinearLayoutManager;引入了 LayoutHelper 的概念,它负责具体的布局逻辑;VirtualLayoutManager管理了一系列LayoutHelper,将具体的布局能力交给LayoutHelper来完成。
  • DelegateAdapterVLayout专门为LayoutHelper定制的Adapter,我们把装载有各种布局的LayoutHelperAdapter放进DelegateAdapter里最后在RecyclerView.setAdapter(DelegateAdapter);就可以加载出复杂的布局。
  • 或许你们会问什么是LayoutHelper,这个问题问得好,就是VLayout提供的九种默认通用布局,解耦所有的View和布局之间的关系: Linear, Grid, 吸顶, 浮动, 固定位置等具体,名称和功能如下:

 

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

 

这就是九种布局对应的类,我们可以用着九个类实现各种复杂的布局,下面我会一一介绍每个布局和效果,以便更直观的看到效果:

 

  • LinearLayoutHelper: 线性布局,就是实现ListView的效果很简单,直接看代码:

 

public class LinearLayoutHelperActivity extends Activity{

 

    public static RecyclerView recyclerview;

 

    public static DelegateRecyclerAdapter delegateRecyclerAdapter;

 

    public DelegateAdapter adapter;

 

    @Override

 

    protected void onCreate(@Nullable Bundle savedInstanceState) {

 

        super.onCreate(savedInstanceState);

 

        setContentView(R.layout.layout_main);

 

        recyclerview=(RecyclerView)findViewById(R.id.recyclerview);

 

        VirtualLayoutManager manager = new VirtualLayoutManager(this);

 

        recyclerview.setLayoutManager(manager);

 

        adapter =new DelegateAdapter(manager, true);

 

 

 

        adapter.addAdapter(init(this));

 

        recyclerview.setAdapter(adapter);

 

    }

 

 

 

    public static DelegateRecyclerAdapter init(Context context){

 

        LinearLayoutHelper linearLayoutHelper=new LinearLayoutHelper();

 

        //设置间隔高度

 

        linearLayoutHelper.setDividerHeight(5);

 

        //设置布局底部与下个布局的间隔

 

        linearLayoutHelper.setMarginBottom(20);

 

        //设置间距

 

        linearLayoutHelper.setMargin(20,20,20,20);

 

        delegateRecyclerAdapter=new DelegateRecyclerAdapter(context,linearLayoutHelper,"LinearLayoutHelper");

 

        return delegateRecyclerAdapter;

 

    }

 

}

 

DelegateRecyclerAdapter的代码如下:

 

public class DelegateRecyclerAdapter extends DelegateAdapter.Adapter{

 

    public Context context;

 

    private LayoutHelper helper;

 

    private LayoutInflater inflater;

 

    private String name;

 

 

 

    public DelegateRecyclerAdapter(Context context,LayoutHelper helper,String name){

 

        this.inflater = LayoutInflater.from(context);

 

        this.helper = helper;

 

        this.context=context;

 

        this.name=name;

 

    }

 

 

 

    @Override

 

    public LayoutHelper onCreateLayoutHelper() {

 

        return this.helper;

 

    }

 

 

 

    @Override

 

    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

 

        return new MyViewHolder(inflater.inflate(R.layout.layout_item,parent,false));

 

    }

 

 

 

    @Override

 

    public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {

 

            if(position%2==0){

 

                holder.itemView.setBackgroundColor(0xaa3F51B5);

 

            }else{

 

                holder.itemView.setBackgroundColor(0xccFF4081);

 

            }

 

        MyViewHolder myViewHolder=(MyViewHolder)holder;

 

        myViewHolder.name.setText(name+position+"");

 

    }

 

 

 

    @Override

 

    public int getItemCount() {

 

        return 9;

 

    }

 

    public class MyViewHolder extends RecyclerView.ViewHolder{

 

        public TextView name;

 

        public MyViewHolder(View itemView) {

 

            super(itemView);

 

            name=(TextView)itemView.findViewById(R.id.item_name);

 

        }

 

    }

 

 

 

}

 

这里需要说的就是在Adapter类里我们需要继承VlayoutDelegateAdapter.Adapter类,然后多回调onCreateLayoutHelper()方法,返回我们传进去的LayoutHelper类,其他的和普通的RecyclerView是一个样的。DelegateRecyclerAdapter在我们后面也有多次引用。其他要说的就是我们初始完LinearLayoutHelper后生产DelegateAdapter.Adapter类再赋给DelegateAdapter,然后然后RecyclerViewsetAdapter()就这样。

 

 

 

  • GridLayoutHelper: Grid布局, 支持横向的colspan,也很简单,代码如下:

 

public static DelegateRecyclerAdapter init(Context context){

 

        GridLayoutHelper gridLayoutHelper=new GridLayoutHelper(4);

 

        //自定义设置某些位置的Item的占格数

 

        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {

 

            @Override

 

            public int getSpanSize(int position) {

 

                if (position >5) {

 

                    return 2;

 

                }else {

 

                    return 1;

 

                }

 

            }

 

        });

 

        //是否填满可用区域

 

        gridLayoutHelper.setAutoExpand(false);

 

        delegateRecyclerAdapter=new DelegateRecyclerAdapter(context,gridLayoutHelper,"GridLayoutHelper");

 

        return delegateRecyclerAdapter;

 

}

 

其他代码很上面的一样。

 

 

 

  • StaggeredGridLayoutHelper: 瀑布流布局,可配置间隔高度/宽度,代码如下:

 

 public static StaggeredAdapter init(Context context){

 

    StaggeredGridLayoutHelper staggeredGridLayoutHelper=new StaggeredGridLayoutHelper(3,20);

 

    staggeredAdapter=new StaggeredAdapter(context,staggeredGridLayoutHelper,"StaggeredGridLayoutHelper");

 

    return staggeredAdapter;

 

 }

 

StaggeredAdapter里我们在onBindViewHolder里用

 

 

 

ViewGroup.LayoutParams layoutParams = ((MyViewholder) holder).text.getLayoutParams();

 

layoutParams.height = 260 + position % 7 * 20;

 

((MyViewholder) holder).text.setLayoutParams(layoutParams);

 

来实现高度不一致,效果如下:

 

 

 

  • FixLayoutHelper: 固定布局,始终在屏幕固定位置显示,代码如下:

 

public static FixLayoutAdapter initFixLayoutHelper(Context context){

 

    FixLayoutHelper fixLayoutHelper=new FixLayoutHelper(FixLayoutHelper.BOTTOM_LEFT, 200, 200);

 

    FixLayoutAdapter fixLayoutAdapter=new FixLayoutAdapter(context,fixLayoutHelper,"fixlayouthelp");

 

    return fixLayoutAdapter;

 

}

 

除了有FixLayoutHelper.BOTTOM_LEFT之外,还有FixLayoutHelper.TOP_LEFTFixLayoutHelper.BOTTOM_RIGHTFixLayoutHelper.TOP_RIGHT, 200,200分别对应偏移量x,y,效果如下:

 

 

 

fixlayouthelp区域块就是FixLayoutHelper了。

 

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

 

public static FixLayoutAdapter initScrollFixLayout(Context context){

 

    ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(15,15);

 

    //show_always:总是显示

 

    //show_on_enter:当页面滚动到这个视图的位置的时候,才显示

 

    //show_on_leave:当页面滚出这个视图的位置的时候显示

 

    scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);

 

    return new FixLayoutAdapter(context, scrollFixLayoutHelper,"scrollfixlayouthelper");

 

}

 

代码很简单,看效果:

 

 

 

ScrollFixLayoutHelper继承自FixLayoutHelper,不同的是showType来决定这个布局的Item是否显示,可以用来做一些返回顶部之类的按钮,

 

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

 

这里效果不明显,等集合所有布局之后大家就可以看很直观的效果

 

  • FloatLayoutHelper: 浮动布局,可以固定显示在屏幕上,但用户可以拖拽其位置,代码如下:

 

public static FixLayoutAdapter initFloatLayoutHelper(Context context){

 

    FloatLayoutHelper floatLayoutHelper=new FloatLayoutHelper();

 

    floatLayoutHelper.setDefaultLocation(20,250);

 

    FixLayoutAdapter fixLayoutAdapter=new FixLayoutAdapter(context,floatLayoutHelper,"floatlayouthelper");

 

    return  fixLayoutAdapter;

 

}

 

其中setDefaultLocation()使用来设置他的初始位置的,setAlignType(表示吸边时的基准位置,默认左上角,有四个取值,分别是TOP_LEFT, TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT

 

  • ColumnLayoutHelper: 栏格布局,都布局在一排,可以配置不同列之间的宽度比值,代码如下:

 

 public static ColumnLayoutAdapter initColumnLayout(Context context){

 

    ColumnLayoutHelper columnLayoutHelper=new ColumnLayoutHelper();

 

    columnLayoutHelper.setWeights(new float[]{20,20,20,20,20});

 

    columnLayoutHelper.setMarginBottom(20);

 

    ColumnLayoutAdapter columnLayoutAdapter=new ColumnLayoutAdapter(context,columnLayoutHelper,"ColumnLayoutHelper");

 

    return columnLayoutAdapter;

 

}

 

ColumnLayoutHelper需要设置Weights,是一个float数组,总和为100,否则超出布局。效果图如下:

 

 

 

  • SingleLayoutHelper: 通栏布局,只会显示一个组件View,这里建议设置Adapter个数为1,因为他就只会显示一栏,假如有多个可能会出现一些问题,本人实测个数多时会出点问题。代码如下:

 

public static SingleLayoutAdapter initSingleLayout(Context context){

 

    SingleLayoutHelper singleLayoutHelper=new SingleLayoutHelper();

 

    //设置间距

 

    singleLayoutHelper.setMargin(20,20,20,20);

 

    SingleLayoutAdapter singleLayoutAdapter=new SingleLayoutAdapter(context,singleLayoutHelper,"SingleLayoutHelper");

 

    return singleLayoutAdapter;

 

}

 

 

 

效果图如下:

 

 

 

 

 

  • OnePlusNLayoutHelper: 一拖N布局,可以配置1-5个子元素,根据个数的不同所呈现的界面也是不一样的,不同个数效果如下:

 

//个数为1

 

 

 

//个数为2

 

 

 

//个数为3

 

 

 

代码如下:

 

 public static OnePlusNLayoutAdapter initOnePlusNLayout(Context context){

 

    OnePlusNLayoutHelper onePlusNLayoutHelper=new OnePlusNLayoutHelper();

 

    //设置布局底部与下个布局的间隔

 

    onePlusNLayoutHelper.setMarginBottom(20);

 

    OnePlusNLayoutAdapter onePlusNLayoutAdapter=new OnePlusNLayoutAdapter(context,onePlusNLayoutHelper,"OnePlusNLayoutHelper");

 

    return onePlusNLayoutAdapter;

 

}

 

  • StickyLayoutHelper: stikcy布局, 可以配置吸顶或者吸底,代码如下:

 

public static StickyLayoutAdapter initStickyLayoutHelper(Context context){

 

    StickyLayoutHelper stickyLayoutHelper=new StickyLayoutHelper();

 

    return new StickyLayoutAdapter(context,stickyLayoutHelper);

 

}

 

 

 

  • 最后假如只是单单加载其中的一个布局其实意义不大,VLayout只最大的意义在于加载多个布局并且保持一个很好的复用,所以我们把上面的所有布局一起加载起来,代码如下:

 

public class AllActivity extends Activity{

 

 

 

    private RecyclerView recyclerview;

 

    private DelegateAdapter delegateAdapter ;

 

    final List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

 

 

 

    @Override

 

    protected void onCreate(@Nullable Bundle savedInstanceState) {

 

        super.onCreate(savedInstanceState);

 

        setContentView(R.layout.layout_main);

 

        recyclerview=(RecyclerView)findViewById(R.id.recyclerview);

 

 

 

        initView();

 

    }

 

 

 

    public void initView(){

 

        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();

 

        recyclerview.setRecycledViewPool(viewPool);

 

        viewPool.setMaxRecycledViews(0,10);

 

 

 

        adapters.add(LinearLayoutHelperActivity.init(this));

 

        adapters.add(ColumnLayoutHelperActivity.initColumnLayout(this));

 

        adapters.add(GridLayoutHelperActivity.init(this));

 

        adapters.add(FixLayoutHelperActivity.initFixLayoutHelper(this));

 

        adapters.add(ScrollFixLayoutHelperActivity.initScrollFixLayout(this));

 

        adapters.add(SingleLayoutHelperActivity.initSingleLayout(this));

 

        adapters.add(OnePlusNLayoutHelperActivity.initOnePlusNLayout(this));

 

        adapters.add(FloatLayoutHelperActivity.initFloatLayoutHelper(this));

 

        adapters.add(StickyLayoutHelperActivity.initStickyLayoutHelper(this));

 

        adapters.add(StaggeredGridLayoutHelperActivity.init(this));

 

 

 

        VirtualLayoutManager manager = new VirtualLayoutManager(this);

 

        recyclerview.setLayoutManager(manager);

 

        delegateAdapter = new DelegateAdapter(manager);

 

 

 

        delegateAdapter.setAdapters(adapters);

 

        recyclerview.setAdapter(delegateAdapter);

 

    }

 

 

 

}

 

 

 

要注意的是DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, hasConsistItemType);里当hasConsistItemType=true的时候,不论是不是属于同一个子adapter,相同类型的item都能复用。表示它们共享一个类型。 当hasConsistItemType=false的时候,不同子adapter之间的类型不共享。

 

 

 

posted @ 2018-05-21 17:33  ChHM  阅读(585)  评论(0编辑  收藏  举报