一、概述
在前面的學習中,我們已經對Adapter
有了大概的了解,在整個RecyclerView
的體系當中,Adapter
負責提供View
,而LayoutManager
負責決定它們在RecyclerView
中擺放的位置以及在窗口中不可見之后的回收策略。今天,我們來一起看一下LayoutManager
的相關知識。
二、LayoutManager
的使用
通過重寫LayoutManager
,我們可以得到各式各樣的布局。官方提供了以下三種LayoutManager
:
LinearLayoutManager
GirdLayoutManager
StaggeredGridLayoutManager
下面,我們就來一起學習它們的使用方式。
2.1 線性布局:LinearLayoutManager
使用這個LinearLayoutManager
時,所有的Item
都是線性排列的,我們可以指定以下兩點。
2.1.1 縱向/橫向排列
- 縱向排列:
LinearLayoutManager.OrientationHelper.VERTICAL
:
- 橫向排列:
LinearLayoutManager.OrientationHelper.HORIZONTAL
:
2.1.2 Item
排列的順序和滑動方向
通過reverse
指定Items
排列的順序:
-
true
:從右向左或從下到上排列,也就是position=0
的Item
位于最右邊或最下面,往左或者往上滑動得到下一個Item
。
-
false
:和上面相反,也就是我們常見的模式。
2.2 宮格布局:GirdLayoutManager
2.2.1 指定某行或某一列的個數
通過spanCount
參數指定,相當于把RecyclerView
的每行或者每列均分為spanCount
個格子,每個Item
可以占據一個或者多個格子,默認情況下每個Item
占據一個格子,也就是均分。
2.2.2 縱向/橫向排列
- 縱向排列:先填滿一行,再從下一行開始填充。
- 橫向排列:先填滿一列,在從下一列開始填充。
2.2.3 reverse
參數
指定了Items
排列的順序:
-
reverse=true
:逆序排列所有的Item
,和2.1.2
的排列方式有關,如果是縱向排列,那么position=0
的Item
位于左下角,如果是橫向排列,那么位于右上角。 -
reverse=false
:position=0
的Item
位于左上角。
2.2.4 指定分配的比例
上面我們說過,spanCount
指定的是分配的格子數,默認情況下每個Item
會占據一個格子,如果想要改變每一行或者每一列Item
分配的比例,那么可以指定它們占據的格子數,如果該行或者該列剩余的格子不夠分配了,那么就換行,但是一定不能夠大于spanCount
的值:
public void setSpanSizeLookup(SpanSizeLookup spanSizeLookup) {
mSpanSizeLookup = spanSizeLookup;
}
下面是一個使用的例子:
private void init() {
mTitles = new ArrayList<>();
for (int i = 0; i < 40; i++) {
mTitles.add(String.valueOf(i));
}
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.rv_content);
GridLayoutManager layoutManager = new GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
return position % 3 == 0 ? 1 : 2;
}
});
recyclerView.setLayoutManager(layoutManager);
LayoutManagerAdapter adapter = new LayoutManagerAdapter(mTitles);
recyclerView.setAdapter(adapter);
}
最終得到效果為:
2.3 瀑布流:StaggeredGridLayoutManager
2.3.1 指定spanCount
和宮格布局類似,可以指定每行或者每列劃分的格子數,但是它不支持讓某個Item
占據多個格子。
2.3.2 橫向或者縱向排列
這個和上面兩個LayoutManager
的原理類似,就不解釋了。
2.3.3 實戰
默認情況下,如果我們只生成一個StaggeredGridLayoutManager
,那么效果會是下面這樣:
因此,我們要在
onBindViewHolder
中動態地改變每個itemView
的高度,這樣才可以達到瀑布流的效果:
@Override
public void onBindViewHolder(LayoutManagerViewHolder holder, int position) {
holder.setTitle(mTitles.get(position));
ViewGroup.LayoutParams layoutParams = holder.itemView.getLayoutParams();
layoutParams.height = 200 + (position % 4) * 200;
holder.itemView.setBackgroundColor(holder.itemView.getResources().getColor(COLOR[position % 5]));
holder.itemView.setLayoutParams(layoutParams);
}
之后,我們會得到下面的效果:
三、小結
平時的開發當中,這幾個布局已經基本能夠滿足我們的需求,如果需要了解自定義LayoutManager
,那么需要對RecyclerView
的整個機制就很好的了解,在分析完原理之后,我們在詳細講解自定義LayoutManager
的方法。
更多文章,歡迎訪問我的 Android 知識梳理系列:
- Android 知識梳理目錄:http://www.lxweimin.com/p/fd82d18994ce
- 個人主頁:http://lizejun.cn
- 個人知識總結目錄:http://lizejun.cn/categories/