RecycleView進階:使用GridLayoutManager.SpanSizeLookup來動態實現具有不同尺寸的Item
前言
現在基本所有的安卓開發都使用RecycleView替換了ListView和GridView,RecycleView使用的靈活性以及其功能的強大相信大家也深有感觸,使用RecycleView我們也可以很方便的實現一些複雜佈局,例如下面這樣的頁面:
該頁面中,同時包含列表,2列的網格,3列的網格,按照我們之前的邏輯,拿到這樣的頁面肯定是在想什麼RecycleView巢狀啦,ScrollView中巢狀RecycleView啦這樣的思路,當然這些思路當然可以實現,但是相比我們今天所要說的這種實現方式而言就顯得不那麼優雅了。
眾所周知RecyclerView 可以通過 GridLayoutManager 實現網格佈局, 但是很少有人知道GridLayoutManager 還可以用來設定網格中指定Item的列數,類似於合併單元格的功能,而所有的這些我們僅僅只需通過定義一個RecycleView列表就可以完成,要實現指定某個item所佔列數的功能我們需要用到GridLayoutManager.SpanSizeLookup這個類,該類是一個抽象類,裡面包含了一個getSpanSize(int position)的抽象方法,該方法的返回值就是指定position所佔的列數,下面我們通過一個具體的案例來了解一下這個類的簡單使用。
使用案例
public class RecyclerViewActivity extends Activity {
private RecyclerView mRecyclerView;
private HomeAdapter mAdapter;
private ArrayList<Model> mDataList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView (R.layout.recyclerview_layout);
initData();
mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview);
GridLayoutManager manager = new GridLayoutManager(this, 4);
manager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
Model model = mDataList.get(position);
if (model.getType() == 0) {
return 4;
} else if(model.getType() == 1){
return 2;
}else{
return 1;
}
}
});
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
mAdapter = new HomeAdapter(this, mDataList);
mRecyclerView.setAdapter(mAdapter);
}
protected void initData() {
mDataList = new ArrayList<Model>();
for (int i = 0; i < 50; i++) {
Model model = new Model();
model.setName(i + "");
if (i == 0) {
model.setType(0);
} else if (i > 0 && i <= 5) {
model.setType(1);
} else {
model.setType(2);
}
mDataList.add(model);
}
}
}
上面我們先是定義了一個4列的網格佈局,然後通過GridLayoutManager.SpanSizeLookup這個類來動態的指定某個item應該佔多少列,此處是動態的判斷type欄位的值,最終效果如下:
(忽略Item之間的padding值)
或者在介面卡Adapter中重寫onattachedtorecyclerview來指定,該方法會在RecyclerView.setAdapter時被呼叫,示例程式碼如下:
@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
RecyclerView.LayoutManager manager = recyclerView.getLayoutManager();
if (manager instanceof GridLayoutManager) {
final GridLayoutManager gridManager = ((GridLayoutManager) manager);
gridManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
@Override
public int getSpanSize(int position) {
int type = getItemViewType(position);
switch (type) {
case TYPE_ITEM_ONE_LEFT:
case TYPE_ITEM_ONE_UP: //這兩種方式都是一列的,所以返回6
return 6;
case TYPE_ITEM_TWO_UP: //兩列,返回3
return 3;
default:
return 6;
}
}
});
}
}