vlayout使用說明(一)

前言

vlayout 的設計思路請參考Tangram 的基礎 —— vlayout(Android)。框架已經開源,歡迎移步到 github上指教。本文介紹 vlayout 的基本使用。

默認實現

  • 默認通用佈局實現,解耦所有的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.0.1),最新的 aar 都會發布到 jcenter 和 MavenCentral 上,確保配置了這兩個倉庫源,然後引入aar依賴:

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

或者maven

// pom.xml in maven
<dependency>
  <groupId>com.alibaba.android</groupId>
  <artifactId>vlayout</artifactId>
  <version>1.0.1</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);

更新:看了很多人寫的demo和源碼解析後,需求提醒注意上述示例代碼裏只針對type=0的item設置了複用池的大小,如果你的頁面有多種type,需要爲每一種類型的分別調整複用池大小參數。

加載數據時有兩種方式:

  • 一種是使用 DelegateAdapter, 可以像平常一樣寫繼承自DelegateAdapter.Adapter的Adapter, 只比之前的Adapter需要多重載onCreateLayoutHelper方法。 其他的和默認Adapter一樣。
DelegateAdapter delegateAdapter = new DelegateAdapter(layoutManager, hasConsistItemType);
recycler.setAdapter(delegateAdapter);

// 之後可以通過 setAdapters 或 addAdapter方法添加DelegateAdapter.Adapter

delegateAdapter.setAdapters(adapters);

// or
public class CustomAdapter extends DelegateAdapter.Adapter {
	......
}

CustomAdapter adapter = new CustomAdapter(data, new GridLayoutHelper());
delegateAdapter.addAdapter(adapter);

更新:hasConsistItemType這個參數有時候容易被人忽略,當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去更新佈局模式。

Demo

詳細代碼參考:github

擴展布局

如果默認的佈局實現滿足不了,你的需求,可以註冊自定義的LayoutHelper來實現佈局邏輯。有三種基類可以供你使用:

  • BaseLayoutHelper:像LinearLayoutHelperGridLayoutHelper等,內部View可以按行回收的佈局,可直接繼承此類,主要實現layoutViews()computeAlignOffset()等方法。
  • AbstractFullFillLayoutHelper:有些佈局內部的View 並不是從上至下排列的順序,即 Adatper 裏的數據順序和物理視圖順序不一致,那麼可能就不能按數據順序佈局和回收,需要一次性佈局、一次性回收。主要實現layoutViews()等方法。可參考OnePlusNLayoutHelper
  • FixAreaLayoutHelper:fix 類型的佈局,子節點不隨頁面滾動而滾動。主要實現layoutViews()beforeLayout()afterLayout()等方法,可參考FixLayoutHelper

相關文章

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章