1. 程式人生 > >RecycleView進階:使用GridLayoutManager.SpanSizeLookup來動態實現具有不同尺寸的Item

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;
                    }
                }
            });
        }
    }