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

猜你喜欢

转载自blog.csdn.net/gpf1320253667/article/details/84500785