日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 


前言

  • V- Layout 是阿里出品的基礎(chǔ) UI 框架,用于快速實(shí)現(xiàn)頁(yè)面的復(fù)雜布局,在手機(jī)天貓 Android版 內(nèi)廣泛使用
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

電商圖

  • 讓人激動(dòng)的是,在上個(gè)月V- Layout終于在Github上開源!

Github - alibaba - vlayout

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 


目錄

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

目錄


1. 為什么要使用 V - Layout

在講解 V - Layout 前,我們先來(lái)搞懂一個(gè)問題:為什么要使用 V - Layout

1.1 背景

  • Android中 UI 性能消耗主要來(lái)自于兩個(gè)方面:
  1. 布局層次嵌套導(dǎo)致多重 measure/layout
  2. View控件的創(chuàng)建和銷毀
  • 為了解決上述問題,現(xiàn)有的解決方式是: 少用嵌套布局 使用 ListView/GirdView/RecyclerView等基礎(chǔ)空間來(lái)處理View的回收與復(fù)用。

但是,很多時(shí)候我們需要在一個(gè)長(zhǎng)列表下做多種類型的布局來(lái)分配各種元素,,特別是電商平臺(tái)首頁(yè)等頁(yè)面,布局元素結(jié)構(gòu)更加復(fù)雜多樣。如下圖:

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

電商圖

此時(shí)的解決方案有所變化:不采用子View的復(fù)用,只采用一個(gè)主要的復(fù)用容器(如ListView 或 RecyclerView+LinearLayoutManager),然后在其中使用嵌套方式直接用各個(gè)組件進(jìn)行拼接,減少了復(fù)用的能力

1.2 問題

這種做法還是會(huì)損失Android應(yīng)用的性能。

1.3 解決方案

  • 通過自定義 LayoutManager 管理所有的布局類型
  • 即阿里出品的基礎(chǔ) UI 框架項(xiàng)目 VirtualLayout就是采用該方式來(lái)解決上述問題

2. 簡(jiǎn)介

  • 定義:VirtualLayout是阿里出品的基礎(chǔ) UI 框架項(xiàng)目
  • 作用:快速實(shí)現(xiàn)復(fù)雜的布局格式的混排 & 通過組件回收提高性能

基于 RecyclerView & LayoutManager擴(kuò)展 目前已在Github開源:Github - alibaba - vlayout

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

效果圖


3. 應(yīng)用場(chǎng)景

  • 復(fù)雜的布局格式混排,如:浮動(dòng)布局、欄格布局、通欄布局、一拖N布局、瀑布流布局,還可以組合使用這些布局
  • 具體場(chǎng)景是:如電商平臺(tái)首頁(yè)、活動(dòng)頁(yè)等等

V - Layout 目前已在手機(jī)天貓 & 淘寶 Android 版內(nèi)廣泛使用

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

實(shí)際應(yīng)用效果圖


4. 原理解析

V - Layout的本質(zhì)原理是:通過自定義一個(gè)VirtualLayoutManager(繼承自 LayoutManager),用于管理一系列LayoutHelper,將具體的布局能力交給LayoutHelper來(lái)完成,從而 快速實(shí)現(xiàn)組合布局 的需求。

每個(gè) LayoutHelper負(fù)責(zé) 頁(yè)面某一個(gè)范圍內(nèi)的布局 V - Layout默認(rèn)實(shí)現(xiàn)了10種默認(rèn)布局:(對(duì)應(yīng)同名的LayoutHelper)
布局類型

4.1 源碼類說(shuō)明

  • V - Layout的源碼類圖如下: UML類圖
  • 具體類說(shuō)明
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • V - Layout默認(rèn)實(shí)現(xiàn)了10種默認(rèn)布局:(對(duì)應(yīng)同名的LayoutHelper)
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

布局類型

下面會(huì)進(jìn)行詳細(xì)介紹。

  • 特別注意:
  1. 每一種LayoutHelper負(fù)責(zé)布局一批組件范圍內(nèi)的組件,不同組件范圍內(nèi)的組件之間,如果類型相同,可以在滑動(dòng)過程中回收復(fù)用。因此回收粒度比較細(xì),且可以跨布局類型復(fù)用。
  2. 支持?jǐn)U展外部:即注冊(cè)新的LayoutHelper,實(shí)現(xiàn)特殊的布局方式。下面會(huì)詳細(xì)說(shuō)明

介紹完類之后,我將詳細(xì)分析 V - Layout的工作流程。


4.2 工作流程

  • V - Layout的工作流程分為 初始化 & 布局流程。如下圖:
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

工作流程

  • 下面我將對(duì)初始化 & 布局流程作詳細(xì)分析。

4.2.1 初始化

  • 在使用 V - layout 快速實(shí)現(xiàn)復(fù)雜布局前,需要先做一系列的初始化工作。

初始化流程與使用普通的 RecyclerView + LayoutManager 初始化流程基本一致:Vlayout的使用者

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

初始化流程

  • 此處的初始化 實(shí)際上 就是 使用者在使用 V - layout 時(shí)需要做的初始化工作。
  • 此處主要先講解下數(shù)據(jù)列表的獲取:本質(zhì)上,是對(duì)頁(yè)面實(shí)體 進(jìn)行 卡片 & 組件的拆解,形成一個(gè)位置列表
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 其他初始化步驟將在下面實(shí)例講解進(jìn)行詳細(xì)說(shuō)明

4.2.2 具體布局流程

  • 當(dāng)完成初始化工作后,每當(dāng)用戶剛打開頁(yè)面第一次渲染布局 或 用戶滑動(dòng)頁(yè)面時(shí),都會(huì)進(jìn)行一次布局流程
  • 布局流程的本質(zhì)是:自定義 VirtualLayoutManager持續(xù)獲取頁(yè)面狀態(tài),并通過LayoutHelperFinder找到對(duì)應(yīng)的LayoutHelper從而實(shí)現(xiàn)對(duì)應(yīng)的布局邏輯,從而快速實(shí)現(xiàn)組合布局 的需求
  • 具體流程如下
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

布局流程


總結(jié)

下面用一張圖總結(jié) V - Layout 的原理 & 工作流程

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

原理 & 工作流程

在講完原理后,接下來(lái)我將如何使用 V - Layout。


5. 使用步驟

  • V - Layout的使用其實(shí)就是上面說(shuō)的初始化工作
  • 使用步驟如下:
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

使用步驟

下面我將對(duì)每個(gè)步驟進(jìn)行詳細(xì)說(shuō)明。

步驟1:創(chuàng)建RecyclerView & VirtualLayoutManager 對(duì)象并進(jìn)行綁定

recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // 創(chuàng)建RecyclerView對(duì)象
        
        VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
        // 創(chuàng)建VirtualLayoutManager對(duì)象
        // 同時(shí)內(nèi)部會(huì)創(chuàng)建一個(gè)LayoutHelperFinder對(duì)象,用來(lái)后續(xù)的LayoutHelper查找

        recyclerView.setLayoutManager(layoutManager);
        // 將VirtualLayoutManager綁定到recyclerView

步驟2:設(shè)置回收復(fù)用池大小

如果一屏內(nèi)相同類型的 View 個(gè)數(shù)比較多,需要設(shè)置一個(gè)合適的大小,防止來(lái)回滾動(dòng)時(shí)重新創(chuàng)建 View)

// 設(shè)置組件復(fù)用回收池
        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
        recyclerView.setRecycledViewPool(viewPool);
        viewPool.setMaxRecycledViews(0, 10);

步驟3:設(shè)置Adapter

設(shè)置 V - Layout的Adapter有兩種方式:

  • 方式1:繼承 自 DelegateAdapter
  • 方式2:繼承 自 VirtualLayoutAdapter
    下面會(huì)進(jìn)行詳細(xì)說(shuō)明:

方式1:繼承 自 DelegateAdapter

  • 定義:DelegateAdapter是V - Layout專門為管理 LayoutHelper定制的 Adapter

繼承自VirtualLayoutAdapter

  • 作用:通過管理不同布局的Adapter,繼而管理不同的 LayoutHelper,從而實(shí)現(xiàn)使用不同組合布局

特別注意:雖不可直接綁定LayoutHelper,但是它內(nèi)部有一個(gè)繼承自RecyclerView.Adapter的內(nèi)部類Adapter可以綁定LayoutHelper; 即通過一個(gè)List把綁定好的Adapter打包起來(lái),再放去DelegateAdapter,這樣就可以實(shí)現(xiàn)組合使用不同的布局

  • 具體做法:

寫法與復(fù)寫系統(tǒng)自帶的Adapter非常類似:只比系統(tǒng)自帶的RecyclerAdapter需要多重載onCreateLayoutHelper方法,其余類似 關(guān)于Android系統(tǒng)自帶的RecyclerAdapter的使用具體請(qǐng)看我寫的文章Android開發(fā):ListView、AdapterView、RecyclerView全面解析

public class MyAdapter extends DelegateAdapter.Adapter<MyAdapter.MainViewHolder> {

// 比系統(tǒng)自帶的RecyclerAdapter需要多重載onCreateLayoutHelper()

    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return layoutHelper;
    }

... // 其余寫法與復(fù)寫系統(tǒng)自帶的Adapter相同
}

方式2:繼承 自 VirtualLayoutAdapter

  • 定義:當(dāng)需要實(shí)現(xiàn)復(fù)雜需求時(shí), 可以通過繼承VirtualLayoutAdapter從而實(shí)現(xiàn)自定義Adapter
  • 具體使用
public class MyAdapter extends VirtualLayoutAdapter {
   ...// 自定義Adapter邏輯
}

步驟4:根據(jù)數(shù)據(jù)列表,創(chuàng)建對(duì)應(yīng)的LayoutHelper

  • 系統(tǒng)以封裝好以下布局類型(對(duì)應(yīng)同名的LayoutHelper)
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

布局類型

  • 具體使用如下:

1. 線性布局(LinearLayoutHelper)

  • 布局說(shuō)明:布局子元素(Item)以線性排布的布局
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
/**
    設(shè)置線性布局
       */
        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
        // 創(chuàng)建對(duì)應(yīng)的LayoutHelper對(duì)象

 // 所有布局的公共屬性(屬性會(huì)在下面詳細(xì)說(shuō)明)
        linearLayoutHelper.setItemCount(4);// 設(shè)置布局里Item個(gè)數(shù)
        linearLayoutHelper.setPadding(10,10,10,10);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        linearLayoutHelper.setMargin(10,10,10,10);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        linearLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        linearLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

 // linearLayoutHelper特有屬性
        linearLayoutHelper.setDividerHeight(1); // 設(shè)置每行Item的距離
     

1. 所有布局的共有屬性說(shuō)明:

a. setItemCount屬性

  • 作用:設(shè)置整個(gè)布局里的Item數(shù)量

如設(shè)置的Item總數(shù)如與Adapter的getItemCount()方法返回的數(shù)量不同,會(huì)取決于后者

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
    public void setItemCount(int Count)

// 具體使用
        linearLayoutHelper.setItemCount(4);

b. Adding & Margin屬性

  • 定義:都是邊距的含義,但二者邊距的定義不同: Padding:是 LayoutHelper 的子元素相對(duì) LayoutHelper 邊緣的距離; Margin:是 LayoutHelper 邊緣相對(duì)父控件(即RecyclerView)的距離。具體如下圖:
    示意圖
  • 具體使用
// 接口示意
    public void setPadding(int leftPadding, int topPadding, int rightPadding, int bottomPadding)
    public void setMargin(int leftMargin, int topMargin, int rightMargin, int bottomMargin)

// 具體使用
        linearLayoutHelper.setPadding(10,10,10,10);
        // 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離

        linearLayoutHelper.setMargin(10,10,10,10);
        // 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離

c. bgColor屬性

  • 作用:設(shè)置布局背景顏色
  • 具體使用:
// 接口示意
public void setBgColor(int bgColor)

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

d. aspectRatio屬性

  • 作用:設(shè)置布局內(nèi)每行布局的寬與高的比。如下圖
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setAspectRatio(float aspectRatio);
// LayoutHelper定義的aspectRatio

((VirutalLayoutManager.LayoutParams) layoutParams).mAspectRatio
// 視圖的LayoutParams定義的aspectRatio
// 在LayoutHelper計(jì)算出視圖寬度之后,用來(lái)確定視圖高度時(shí)使用的,它會(huì)覆蓋通過LayoutHelper的aspectRatio計(jì)算出來(lái)的視圖高度,因此具備更高優(yōu)先級(jí)。

// 具體使用
        linearLayoutHelper.setAspectRatio(6);
       

2. LinearLayoutHelper布局的特有屬性說(shuō)明

a. dividerHeight屬性

  • 作用:設(shè)置每行Item之間的距離

設(shè)置的間隔會(huì)與RecyclerView的addItemDecoration()添加的間隔疊加

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setDividerHeight(int dividerHeight)

// 具體使用
 linearLayoutHelper.setDividerHeight(1);


2. 網(wǎng)格布局(GridLayout)

  • 布局說(shuō)明:布局里的Item以網(wǎng)格的形式進(jìn)行排列
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
        /**
        設(shè)置Grid布局
        */
        GridLayoutHelper gridLayoutHelper = new GridLayoutHelper(3);
        // 在構(gòu)造函數(shù)設(shè)置每行的網(wǎng)格個(gè)數(shù)

        // 公共屬性
        gridLayoutHelper.setItemCount(6);// 設(shè)置布局里Item個(gè)數(shù)
        gridLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        gridLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        gridLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        gridLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // gridLayoutHelper特有屬性(下面會(huì)詳細(xì)說(shuō)明)
        gridLayoutHelper.setWeights(new float[]{40, 30, 30});//設(shè)置每行中 每個(gè)網(wǎng)格寬度 占 每行總寬度 的比例
        gridLayoutHelper.setVGap(20);// 控制子元素之間的垂直間距
        gridLayoutHelper.setHGap(20);// 控制子元素之間的水平間距
        gridLayoutHelper.setAutoExpand(false);//是否自動(dòng)填充空白區(qū)域
        gridLayoutHelper.setSpanCount(3);// 設(shè)置每行多少個(gè)網(wǎng)格
        // 通過自定義SpanSizeLookup來(lái)控制某個(gè)Item的占網(wǎng)格個(gè)數(shù)
        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (position > 7 ) {
                    return 3;
                    // 第7個(gè)位置后,每個(gè)Item占3個(gè)網(wǎng)格
                }else {
                    return 2;
                    // 第7個(gè)位置前,每個(gè)Item占2個(gè)網(wǎng)格
                }
            }
        });

GridLayoutHelper布局的特有屬性說(shuō)明

a. weights屬性

  • 作用:設(shè)置每行中每個(gè)網(wǎng)格寬度占每行總寬度的比例

默認(rèn)情況下,每行中每個(gè)網(wǎng)格中的寬度相等 weights屬性是一個(gè)float數(shù)組,每一項(xiàng)代表當(dāng)個(gè)網(wǎng)格占每行總寬度的百分比;總和是100,否則布局會(huì)超出容器寬度; 如果布局中有4列,那么weights的長(zhǎng)度也應(yīng)該是4;長(zhǎng)度大于4,多出的部分不參與寬度計(jì)算;如果小于4,不足的部分默認(rèn)平分剩余的空間。

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setWeights(float[] weights)

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

b. vGap、hGap屬性

  • 作用:分別控制子元素之間的垂直間距 和 水平間距。
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
    public void setHGap(int hGap)
    public void setVGap(int vGap)

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

c. spanCount、spanSizeLookup屬性

  • 作用: spanCount:設(shè)置每行多少個(gè)網(wǎng)格 spanSizeLookup:設(shè)置每個(gè) Item占用多少個(gè)網(wǎng)格(默認(rèn)= 1)
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setSpanCount(int spanCount)
public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup)

// 具體使用
        gridLayoutHelper.setSpanCount(5);// 設(shè)置每行多少個(gè)網(wǎng)格

        // 通過自定義SpanSizeLookup來(lái)控制某個(gè)Item的占網(wǎng)格個(gè)數(shù)
        gridLayoutHelper.setSpanSizeLookup(new GridLayoutHelper.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                if (position > 7 ) {
                    return 3;
                    // 第7個(gè)位置后,每個(gè)Item占3個(gè)網(wǎng)格
                }else {
                    return 2;
                    // 第7個(gè)位置前,每個(gè)Item占2個(gè)網(wǎng)格
                }
            }
        });

d. autoExpand屬性

  • 作用:當(dāng)一行里item的個(gè)數(shù) < (每行網(wǎng)格列數(shù) - spanCount值/ 每個(gè)Item占有2個(gè)網(wǎng)格-setSpanSizeLookup )時(shí),是否自動(dòng)填滿空白區(qū)域

若autoExpand=true,那么視圖的總寬度會(huì)填滿可用區(qū)域; 否則會(huì)在屏幕上留空白區(qū)域。

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setAutoExpand(boolean isAutoExpand)

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

3. 固定布局(FixLayoutHelper)

  • 布局說(shuō)明:布局里的Item 固定位置

固定在屏幕某個(gè)位置,且不可拖拽 & 不隨頁(yè)面滾動(dòng)而滾動(dòng)。如下圖:(左上角)

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

固定布局

  • 具體使用
/**
         設(shè)置固定布局
         */

        FixLayoutHelper fixLayoutHelper = new FixLayoutHelper(FixLayoutHelper.TOP_LEFT,40,100);
        // 參數(shù)說(shuō)明:
        // 參數(shù)1:設(shè)置吸邊時(shí)的基準(zhǔn)位置(alignType) - 有四個(gè)取值:TOP_LEFT(默認(rèn)), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
        // 參數(shù)2:基準(zhǔn)位置的偏移量x
        // 參數(shù)3:基準(zhǔn)位置的偏移量y


        // 公共屬性
        fixLayoutHelper.setItemCount(1);// 設(shè)置布局里Item個(gè)數(shù)
        // 從設(shè)置Item數(shù)目的源碼可以看出,一個(gè)FixLayoutHelper只能設(shè)置一個(gè)
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        fixLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        fixLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        fixLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        fixLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // fixLayoutHelper特有屬性
        fixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// 設(shè)置吸邊時(shí)的基準(zhǔn)位置(alignType)
        fixLayoutHelper.setX(30);// 設(shè)置基準(zhǔn)位置的橫向偏移量X
        fixLayoutHelper.setY(50);// 設(shè)置基準(zhǔn)位置的縱向偏移量Y

FixLayoutHelper特有屬性說(shuō)明

a. AlignType、x、y屬性

  • 作用: alignType:吸邊基準(zhǔn)類型 共有4個(gè)取值:TOP_LEFT(默認(rèn)), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,具體請(qǐng)看下面示意圖 x:基準(zhǔn)位置的橫向偏移量 y:基準(zhǔn)位置的縱向偏移量
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 作用對(duì)象:FixLayoutHelper, ScrollFixLayoutHelper, FloatLayoutHelper的屬性
// 接口示意
public void setAlignType(int alignType)
public void setX(int x)
public void setY(int y)

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

4. 可選顯示的固定布局(ScrollFixLayoutHelper)

  • 布局說(shuō)明:布局里的Item 固定位置

固定在屏幕某個(gè)位置,且不可拖拽 & 不隨頁(yè)面滾動(dòng)而滾動(dòng)(繼承自固定布局(FixLayoutHelper)) 唯一不同的是,可以自由設(shè)置該Item什么時(shí)候顯示(到頂部顯示 / 到底部顯示),可如下圖:(左上角) 需求場(chǎng)景:到頁(yè)面底部顯示”一鍵到頂部“的按鈕功能

以下示意圖為:滑動(dòng)到底部,布局才在左上角顯示

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

滑動(dòng)到底部才在左上角顯示

  • 具體使用
/**
         設(shè)置可選固定布局
         */

        ScrollFixLayoutHelper scrollFixLayoutHelper = new ScrollFixLayoutHelper(ScrollFixLayoutHelper.TOP_RIGHT,0,0);
        // 參數(shù)說(shuō)明:
        // 參數(shù)1:設(shè)置吸邊時(shí)的基準(zhǔn)位置(alignType) - 有四個(gè)取值:TOP_LEFT(默認(rèn)), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT
        // 參數(shù)2:基準(zhǔn)位置的偏移量x
        // 參數(shù)3:基準(zhǔn)位置的偏移量y

        // 公共屬性
        scrollFixLayoutHelper.setItemCount(1);// 設(shè)置布局里Item個(gè)數(shù)
        // 從設(shè)置Item數(shù)目的源碼可以看出,一個(gè)FixLayoutHelper只能設(shè)置一個(gè)
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        scrollFixLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        scrollFixLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        scrollFixLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        scrollFixLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // fixLayoutHelper特有屬性
     scrollFixLayoutHelper.setAlignType(FixLayoutHelper.TOP_LEFT);// 設(shè)置吸邊時(shí)的基準(zhǔn)位置(alignType)
        scrollFixLayoutHelper.setX(30);// 設(shè)置基準(zhǔn)位置的橫向偏移量X
        scrollFixLayoutHelper.setY(50);// 設(shè)置基準(zhǔn)位置的縱向偏移量Y
        scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);// 設(shè)置Item的顯示模式

ScrollFixLayoutHelper特有屬性說(shuō)明

a. AlignType、x、y屬性

  • 作用: alignType:吸邊基準(zhǔn)類型 共有4個(gè)取值:TOP_LEFT(默認(rèn)), TOP_RIGHT, BOTTOM_LEFT, BOTTOM_RIGHT,具體請(qǐng)看下面示意圖 x:基準(zhǔn)位置的橫向偏移量 y:基準(zhǔn)位置的縱向偏移量
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
// 接口示意
public void setAlignType(int alignType)
public void setX(int x)
public void setY(int y)

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

b. ShowType屬性

  • 作用:設(shè)置Item的顯示模式

共有三種顯示模式

SHOW_ALWAYS:永遠(yuǎn)顯示(即效果同固定布局) SHOW_ON_ENTER:默認(rèn)不顯示視圖,當(dāng)頁(yè)面滾動(dòng)到該視圖位置時(shí)才顯示; SHOW_ON_LEAVE:默認(rèn)不顯示視圖,當(dāng)頁(yè)面滾出該視圖位置時(shí)才顯示

  • 具體使用
// 接口示意
public void setShowType(int showType)

// 具體使用
scrollFixLayoutHelper.setShowType(ScrollFixLayoutHelper.SHOW_ON_ENTER);

5. 浮動(dòng)布局(FloatLayoutHelper)

  • 布局說(shuō)明:布局里的Item只有一個(gè)

可隨意拖動(dòng),但最終會(huì)被吸邊到兩側(cè) 不隨頁(yè)面滾動(dòng)而移動(dòng)

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
/**
         設(shè)置浮動(dòng)布局
         */
        FloatLayoutHelper floatLayoutHelper = new FloatLayoutHelper();
        // 創(chuàng)建FloatLayoutHelper對(duì)象

        // 公共屬性
        floatLayoutHelper.setItemCount(1);// 設(shè)置布局里Item個(gè)數(shù)
        // 從設(shè)置Item數(shù)目的源碼可以看出,一個(gè)FixLayoutHelper只能設(shè)置一個(gè)
//        @Override
//        public void setItemCount(int itemCount) {
//            if (itemCount > 0) {
//                super.setItemCount(1);
//            } else {
//                super.setItemCount(0);
//            }
//        }
        floatLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        floatLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        floatLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        floatLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // floatLayoutHelper特有屬性
        floatLayoutHelper.setDefaultLocation(300,300);// 設(shè)置布局里Item的初始位置

        

6. 欄格布局(ColumnLayoutHelper)

  • 布局說(shuō)明:該布局只設(shè)有一欄(該欄設(shè)置多個(gè)Item)

可理解為只有一行的線性布局

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

/**
         設(shè)置欄格布局
         */
        ColumnLayoutHelper columnLayoutHelper = new ColumnLayoutHelper();
        // 創(chuàng)建對(duì)象

        // 公共屬性
        columnLayoutHelper.setItemCount(3);// 設(shè)置布局里Item個(gè)數(shù)
        columnLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        columnLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        columnLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        columnLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // columnLayoutHelper特有屬性
        columnLayoutHelper.setWeights(new float[]{30, 40, 30});// 設(shè)置該行每個(gè)Item占該行總寬度的比例
        // 同上面Weigths屬性講解


7. 通欄布局(SingleLayoutHelper)

  • 布局說(shuō)明:布局只有一欄,該欄只有一個(gè)Item
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
/**
         設(shè)置通欄布局
         */

        SingleLayoutHelper singleLayoutHelper = new SingleLayoutHelper();

        // 公共屬性
        singleLayoutHelper.setItemCount(3);// 設(shè)置布局里Item個(gè)數(shù)
        singleLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        singleLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        singleLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        singleLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比
        


8. 一拖N布局 (OnePlusNLayoutHelper)

  • 布局說(shuō)明:將布局分為不同比例,最多是1拖4。具體如下圖
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖1

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖2

  • 具體使用
/**
         設(shè)置1拖N布局
         */
        OnePlusNLayoutHelper onePlusNLayoutHelper = new OnePlusNLayoutHelper(5);
        // 在構(gòu)造函數(shù)里傳入顯示的Item數(shù)
        // 最多是1拖4,即5個(gè)

        // 公共屬性
        onePlusNLayoutHelper.setItemCount(3);// 設(shè)置布局里Item個(gè)數(shù)
        onePlusNLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        onePlusNLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        onePlusNLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        onePlusNLayoutHelper.setAspectRatio(3);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比


9. 吸邊布局(StickyLayoutHelper)

  • 布局說(shuō)明:布局只有一個(gè)Item,顯示邏輯如下: 當(dāng)它包含的組件處于屏幕可見范圍內(nèi)時(shí),像正常的組件一樣隨頁(yè)面滾動(dòng)而滾動(dòng) 當(dāng)組件將要被滑出屏幕返回的時(shí)候,可以吸到屏幕的頂部或者底部,實(shí)現(xiàn)一種吸住的效果
  • 示意圖(吸在頂部)
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
        /**
         設(shè)置吸邊布局
         */
        StickyLayoutHelper stickyLayoutHelper = new StickyLayoutHelper();

        // 公共屬性
        stickyLayoutHelper.setItemCount(3);// 設(shè)置布局里Item個(gè)數(shù)
        stickyLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        stickyLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        stickyLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        stickyLayoutHelper.setAspectRatio(3);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // 特有屬性
        stickyLayoutHelper.setStickyStart(true);
        // true = 組件吸在頂部
        // false = 組件吸在底部

        stickyLayoutHelper.setOffset(100);// 設(shè)置吸邊位置的偏移量

        Adapter_StickyLayout = new MyAdapter(this, stickyLayoutHelper,1, listItem) {
            // 設(shè)置需要展示的數(shù)據(jù)總數(shù),此處設(shè)置是1
            // 為了展示效果,通過重寫onBindViewHolder()將布局的第一個(gè)數(shù)據(jù)設(shè)置為Stick
            @Override
            public void onBindViewHolder(MainViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                if (position == 0) {
                    holder.Text.setText("Stick");
                }
            }
        };

        adapters.add(Adapter_StickyLayout) ;
        // 將當(dāng)前的Adapter加入到Adapter列表里

stickyStart、 offset屬性說(shuō)明

  • 作用: stickyStart:設(shè)置吸邊位置 當(dāng)視圖的位置在屏幕范圍內(nèi)時(shí),視圖會(huì)隨頁(yè)面滾動(dòng)而滾動(dòng);當(dāng)視圖的位置滑出屏幕時(shí),StickyLayoutHelper會(huì)將視圖固定在頂部(stickyStart = true)或 底部(stickyStart = false) offset:設(shè)置吸邊的偏移量
  • 具體使用
// 接口示意
        public void setStickyStart(boolean stickyStart)
        public void setOffset(int offset)

// 具體使用
        stickyLayoutHelper.setStickyStart(true);
        // true = 組件吸在頂部
        // false = 組件吸在底部
        stickyLayoutHelper.setOffset(100);// 設(shè)置吸邊位置的偏移量

10. 瀑布流布局(StaggeredGridLayoutHelper)

  • 布局說(shuō)明:以網(wǎng)格的形式進(jìn)行布局。與網(wǎng)格布局類似,區(qū)別在于: 網(wǎng)格布局每欄的Item高度是相等的; 瀑布流布局每欄的Item高度是可以不相等的。
Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

 

示意圖

  • 具體使用
        /**
         設(shè)置瀑布流布局
         */

        StaggeredGridLayoutHelper staggeredGridLayoutHelper = new StaggeredGridLayoutHelper();
        // 創(chuàng)建對(duì)象

        // 公有屬性
        staggeredGridLayoutHelper.setItemCount(20);// 設(shè)置布局里Item個(gè)數(shù)
        staggeredGridLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        staggeredGridLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        staggeredGridLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        staggeredGridLayoutHelper.setAspectRatio(3);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // 特有屬性
        staggeredGridLayoutHelper.setLane(3);// 設(shè)置控制瀑布流每行的Item數(shù)
        staggeredGridLayoutHelper.setHGap(20);// 設(shè)置子元素之間的水平間距
        staggeredGridLayoutHelper.setVGap(15);// 設(shè)置子元素之間的垂直間距

       

自定義布局(即自定義LayoutHelper)

除了使用系統(tǒng)提供的默認(rèn)布局 LayoutHelper,開發(fā)者還可以通過自定義LayoutHelper從而實(shí)現(xiàn)自定義布局樣式。有三種方式:

  1. 繼承BaseLayoutHelper:從上而下排列的順序 & 內(nèi)部 View可以按行回收的布局;主要實(shí)現(xiàn)layoutViews()、computeAlignOffset()等方法

LinearLayoutHelper、GridLayoutHelper都是采用該方法實(shí)現(xiàn)

  1. 繼承AbstractFullFillLayoutHelper:有些布局內(nèi)部的 View 并不是從上至下排列的順序(即 Adatper 里的數(shù)據(jù)順序和物理視圖順序不一致,那么可能就不能按數(shù)據(jù)順序布局和回收),需要一次性布局
    & 回收。主要實(shí)現(xiàn)layoutViews()等方法

OnePlusNLayoutHelper采用該方法實(shí)現(xiàn)

  1. 繼承FixAreaLayoutHelper:fix 類型布局,子節(jié)點(diǎn)不隨頁(yè)面滾動(dòng)而滾動(dòng)。主要實(shí)現(xiàn)layoutViews()、beforeLayout()、afterLayout()等方法

FixLayoutHelper采用該方法實(shí)現(xiàn)


步驟5:將生成的LayoutHelper 交給Adapter,并綁定到RecyclerView 對(duì)象

此處的做法會(huì)因步驟3中Adapter的設(shè)置而有所不同

<-- Adapter繼承 自 DelegateAdapter -->

// 步驟1:設(shè)置Adapter列表(同時(shí)也是設(shè)置LayoutHelper列表)
        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

// 步驟2:創(chuàng)建自定義的Adapter對(duì)象 & 綁定數(shù)據(jù) & 綁定上述對(duì)應(yīng)的LayoutHelper
// 綁定你需要展示的布局LayoutHelper即可,此處僅展示兩個(gè)。
        MyAdapter Adapter_linearLayout    = new MyAdapter(this, linearLayoutHelper,ListItem);
// ListItem是需要綁定的數(shù)據(jù)(其實(shí)取決于你的Adapter如何定義)

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

// 步驟3:將創(chuàng)建的Adapter對(duì)象放入到DelegateAdapter.Adapter列表里
        adapters.add(Adapter_linearLayout ) ;
        adapters.add(Adapter_gridLayoutHelper ) ;

// 步驟4:創(chuàng)建DelegateAdapter對(duì)象 & 將layoutManager綁定到DelegateAdapter
DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager);

// 步驟5:將DelegateAdapter.Adapter列表綁定到DelegateAdapter
 delegateAdapter.setAdapters(adapters);

// 步驟6:將delegateAdapter綁定到recyclerView
recyclerView.setAdapter(delegateAdapter);



<-- Adapter繼承 自 VirtualLayoutAdapter -->

// 步驟1:設(shè)置LayoutHelper列表
        List<LayoutHelper> helpers = new LinkedList<>();

// 步驟2:綁定上述對(duì)應(yīng)的LayoutHelper
helpers.add(Adapter_linearLayout );
helpers.add(Adapter_gridLayoutHelper ) ;

// 步驟3:創(chuàng)建自定義的MyAdapter對(duì)象 & 綁定layoutManager
MyAdapter myAdapter = new MyAdapter(layoutManager);

// 步驟4:將 layoutHelper 列表傳遞給 adapter
myAdapter.setLayoutHelpers(helpers);

// 步驟5:將adapter綁定到recyclerView
recycler.setAdapter(myAdapter);

至此,使用過程講解完畢。


6. 實(shí)例說(shuō)明

  • V-Layout的優(yōu)點(diǎn)在于快速的組合不同布局
  • 下面,我將根據(jù)上面的步驟說(shuō)明,用一個(gè)實(shí)例來(lái)使用 V - Layout快速組合布局

步驟1:在Android - Gradle加入依賴

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

步驟2:定義主 xml布局

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="scut.carson_ho.v_layoutusage.MainActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/my_recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scrollbars="horizontal" />
</RelativeLayout>

步驟3:定義 RecyclerView每個(gè)子元素( Item )的xml布局

item.xml

此處定義的 Item 布局是常用的 上字下圖

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="New Text"
        android:id="@+id/Item" />

    <ImageView
        android:layout_alignParentRight="true"
        android:layout_gravity="center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/Image"/>

</LinearLayout>

步驟4:設(shè)置Adapter

  • 設(shè)置 V - Layout的Adapter有兩種方式: 繼承 自 DelegateAdapter

此處主要以該方式進(jìn)行演示

  1. 繼承 自 VirtualLayoutAdapter
  • 具體使用

MyAdapter.JAVA

public class MyAdapter extends DelegateAdapter.Adapter<MyAdapter.MainViewHolder> {
    // 使用DelegateAdapter首先就是要自定義一個(gè)它的內(nèi)部類Adapter,讓LayoutHelper和需要綁定的數(shù)據(jù)傳進(jìn)去
    // 此處的Adapter和普通RecyclerView定義的Adapter只相差了一個(gè)onCreateLayoutHelper()方法,其他的都是一樣的做法.

    private ArrayList<HashMap<String, Object>> listItem;
    // 用于存放數(shù)據(jù)列表

    private Context context;
    private LayoutHelper layoutHelper;
    private RecyclerView.LayoutParams layoutParams;
    private int count = 0;

    private MyItemClickListener myItemClickListener;
    // 用于設(shè)置Item點(diǎn)擊事件

    //構(gòu)造函數(shù)(傳入每個(gè)的數(shù)據(jù)列表 & 展示的Item數(shù)量)
    public MyAdapter(Context context, LayoutHelper layoutHelper, int count, ArrayList<HashMap<String, Object>> listItem) {
        this(context, layoutHelper, count, new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 300), listItem);
    }

    public MyAdapter(Context context, LayoutHelper layoutHelper, int count, @NonNull RecyclerView.LayoutParams layoutParams, ArrayList<HashMap<String, Object>> listItem) {
        this.context = context;
        this.layoutHelper = layoutHelper;
        this.count = count;
        this.layoutParams = layoutParams;
        this.listItem = listItem;
    }

    // 把ViewHolder綁定Item的布局
    @Override
    public MainViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        return new MainViewHolder(LayoutInflater.from(context).inflate(R.layout.item, parent, false));
    }

    // 此處的Adapter和普通RecyclerView定義的Adapter只相差了一個(gè)onCreateLayoutHelper()方法
    @Override
    public LayoutHelper onCreateLayoutHelper() {
        return layoutHelper;
    }

    // 綁定Item的數(shù)據(jù)
    @Override
    public void onBindViewHolder(MainViewHolder holder, int position) {
        holder.Text.setText((String) listItem.get(position).get("ItemTitle"));
        holder.image.setImageResource((Integer) listItem.get(position).get("ItemImage"));

    }

    // 返回Item數(shù)目
    @Override
    public int getItemCount() {
        return count;
    }

    // 設(shè)置Item的點(diǎn)擊事件
    // 綁定MainActivity傳進(jìn)來(lái)的點(diǎn)擊監(jiān)聽器
    public void setOnItemClickListener(MyItemClickListener listener) {
        myItemClickListener = listener;
    }

    
    //定義Viewholder
    class MainViewHolder extends RecyclerView.ViewHolder {
        public TextView Text;
        public ImageView image;

        public MainViewHolder(View root) {
            super(root);
            
            // 綁定視圖
            Text = (TextView) root.findViewById(R.id.Item);
            image = (ImageView) root.findViewById(R.id.Image);

            root.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (myItemClickListener != null)
                        myItemClickListener.onItemClick(v, getPosition());
                }

            }
            //監(jiān)聽到點(diǎn)擊就回調(diào)MainActivity的onItemClick函數(shù)
            );

        }

        public TextView getText() {
            return Text;
        }
    }
}

以下步驟都將寫在同一個(gè).Java文件里

步驟5:創(chuàng)建RecyclerView & VirtualLayoutManager 對(duì)象并進(jìn)行綁定 步驟6:設(shè)置回收復(fù)用池大小 步驟7:設(shè)置需要存放的數(shù)據(jù) 步驟8:根據(jù)數(shù)據(jù)列表,創(chuàng)建對(duì)應(yīng)的LayoutHelper 步驟9:將生成的LayoutHelper 交給Adapter,并綁定到RecyclerView 對(duì)象

詳細(xì)請(qǐng)看注釋

MainActivity.java

public class MainActivity extends AppCompatActivity implements MyItemClickListener {
    RecyclerView recyclerView;
    MyAdapter Adapter_linearLayout,Adapter_GridLayout,Adapter_FixLayout,Adapter_ScrollFixLayout
            ,Adapter_FloatLayout,Adapter_ColumnLayout,Adapter_SingleLayout,Adapter_onePlusNLayout,
            Adapter_StickyLayout,Adapter_StaggeredGridLayout;
    private ArrayList<HashMap<String, Object>> listItem;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**
         * 步驟1:創(chuàng)建RecyclerView & VirtualLayoutManager 對(duì)象并進(jìn)行綁定
         * */
        recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);
        // 創(chuàng)建RecyclerView對(duì)象

        VirtualLayoutManager layoutManager = new VirtualLayoutManager(this);
        // 創(chuàng)建VirtualLayoutManager對(duì)象
        // 同時(shí)內(nèi)部會(huì)創(chuàng)建一個(gè)LayoutHelperFinder對(duì)象,用來(lái)后續(xù)的LayoutHelper查找

        recyclerView.setLayoutManager(layoutManager);
        // 將VirtualLayoutManager綁定到recyclerView

        /**
         * 步驟2:設(shè)置組件復(fù)用回收池
         * */
        RecyclerView.RecycledViewPool viewPool = new RecyclerView.RecycledViewPool();
        recyclerView.setRecycledViewPool(viewPool);
        viewPool.setMaxRecycledViews(0, 10);

        /**
         * 步驟3:設(shè)置需要存放的數(shù)據(jù)
         * */
        listItem = new ArrayList<HashMap<String, Object>>();
        for (int i = 0; i < 100; i++) {
            HashMap<String, Object> map = new HashMap<String, Object>();
            map.put("ItemTitle", "第" + i + "行");
            map.put("ItemImage", R.mipmap.ic_launcher);
            listItem.add(map);

        }

        /**
         * 步驟4:根據(jù)數(shù)據(jù)列表,創(chuàng)建對(duì)應(yīng)的LayoutHelper
         * */

        // 為了展示效果,此處將上面介紹的所有布局都顯示出來(lái)

        /**
         設(shè)置線性布局
         */
        LinearLayoutHelper linearLayoutHelper = new LinearLayoutHelper();
        // 創(chuàng)建對(duì)應(yīng)的LayoutHelper對(duì)象

        // 公共屬性
        linearLayoutHelper.setItemCount(4);// 設(shè)置布局里Item個(gè)數(shù)
        linearLayoutHelper.setPadding(20, 20, 20, 20);// 設(shè)置LayoutHelper的子元素相對(duì)LayoutHelper邊緣的距離
        linearLayoutHelper.setMargin(20, 20, 20, 20);// 設(shè)置LayoutHelper邊緣相對(duì)父控件(即RecyclerView)的距離
        // linearLayoutHelper.setBgColor(Color.GRAY);// 設(shè)置背景顏色
        linearLayoutHelper.setAspectRatio(6);// 設(shè)置設(shè)置布局內(nèi)每行布局的寬與高的比

        // linearLayoutHelper特有屬性
        linearLayoutHelper.setDividerHeight(10);
        // 設(shè)置間隔高度
        // 設(shè)置的間隔會(huì)與RecyclerView的addItemDecoration()添加的間隔疊加.

        linearLayoutHelper.setMarginBottom(100);
        // 設(shè)置布局底部與下個(gè)布局的間隔


        // 創(chuàng)建自定義的Adapter對(duì)象 & 綁定數(shù)據(jù) & 綁定對(duì)應(yīng)的LayoutHelper進(jìn)行布局繪制
         Adapter_linearLayout  = new MyAdapter(this, linearLayoutHelper, 4, listItem) {
             // 參數(shù)2:綁定綁定對(duì)應(yīng)的LayoutHelper
             // 參數(shù)3:傳入該布局需要顯示的數(shù)據(jù)個(gè)數(shù)
             // 參數(shù)4:傳入需要綁定的數(shù)據(jù)

             // 通過重寫onBindViewHolder()設(shè)置更豐富的布局效果
             @Override
             public void onBindViewHolder(MainViewHolder holder, int position) {
                 super.onBindViewHolder(holder, position);
                 // 為了展示效果,將布局的第一個(gè)數(shù)據(jù)設(shè)置為linearLayout
                 if (position == 0) {
                     holder.Text.setText("Linear");
                 }

                  //為了展示效果,將布局里不同位置的Item進(jìn)行背景顏色設(shè)置
                 if (position < 2) {
                     holder.itemView.setBackgroundColor(0x66cc0000 + (position - 6) * 128);
                 } else if (position % 2 == 0) {
                     holder.itemView.setBackgroundColor(0xaa22ff22);
                 } else {
                     holder.itemView.setBackgroundColor(0xccff22ff);
                 }

             }
         };

        Adapter_linearLayout.setOnItemClickListener(this);
        // 設(shè)置每個(gè)Item的點(diǎn)擊事件

        ....// 還有其他布局,由于代碼量就較多就不貼出來(lái)了。

        /**
         *步驟5:將生成的LayoutHelper 交給Adapter,并綁定到RecyclerView 對(duì)象
         **/

        // 1. 設(shè)置Adapter列表(同時(shí)也是設(shè)置LayoutHelper列表)
        List<DelegateAdapter.Adapter> adapters = new LinkedList<>();

        // 2. 將上述創(chuàng)建的Adapter對(duì)象放入到DelegateAdapter.Adapter列表里
        adapters.add(Adapter_linearLayout) ;
        adapters.add(Adapter_StickyLayout) ;
        adapters.add(Adapter_ScrollFixLayout) ;
        adapters.add(Adapter_GridLayout) ;
        adapters.add(Adapter_FixLayout) ;
        adapters.add(Adapter_FloatLayout) ;
        adapters.add(Adapter_ColumnLayout) ;
        adapters.add(Adapter_SingleLayout) ;
        adapters.add(Adapter_onePlusNLayout) ;
        adapters.add(Adapter_StaggeredGridLayout) ;

        // 3. 創(chuàng)建DelegateAdapter對(duì)象 & 將layoutManager綁定到DelegateAdapter
        DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager);

        // 4. 將DelegateAdapter.Adapter列表綁定到DelegateAdapter
        delegateAdapter.setAdapters(adapters);

        // 5. 將delegateAdapter綁定到recyclerView
        recyclerView.setAdapter(delegateAdapter);


        /**
         *步驟6:Item之間的間隔
         **/

        recyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
                outRect.set(5, 5, 5, 5);
            }
        });


    }

    /**
     *步驟7:實(shí)現(xiàn)Item點(diǎn)擊事件
     **/
    // 點(diǎn)擊事件的回調(diào)函數(shù)
    @Override
    public void onItemClick(View view, int postion) {
        System.out.println("點(diǎn)擊了第"+postion+"行");
        Toast.makeText(this, (String) listItem.get(postion).get("ItemTitle"), Toast.LENGTH_SHORT).show();
    }
}

效果圖

Android開源庫(kù)V-Layout:淘寶,天貓都在用的UI框架,趕緊用起來(lái)吧

分享到:
標(biāo)簽:開源 Android
用戶無(wú)頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定