RecycleView实现带有section header/footer的多列列表

  RecycleView功能比较强大,自由度比较高,能实现各种各样的布局。对于像多列布局,或者增加header/footer这种情况,也是比较方便能够实现。下面一步一步来实现带有section的多列列表。
  首先实现多列列表,这个就很容易直接布局样式改为GridLayoutManager,然后设置spanCount即可。如果某一列的item数目是不固定的,那么需要通过设置SpanSizeLookup来实现:

gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                //  这里的position就是item所在的position
                if (position == 0) {
                      // 例如第一行一列
                      return 1;
                } else {
                      // 其他行展示两列
                      return 2;
                }
            }
        });

接下来加入section header和footer,这里一般如果简单一点的布局直接在第一行加入header和最后一行加入footer,这里可以用itemViewType来实现不同的section,代码如下:

public class MainActivity extends AppCompatActivity {

    private RecyclerView rvTest;
    private MyAdapter mAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        rvTest = findViewById(R.id.rv_test);

        mAdapter = new MyAdapter();
        final GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        rvTest.setLayoutManager(gridLayoutManager);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                // 表示一个item占用几份
                if (position == 0 || position == mAdapter.getItemCount()-1) {
                    // 由于GridLayoutManager设置的每行2份, header和footer要独占一行, 所以设置为2份, 也即spanCount
                    return gridLayoutManager.getSpanCount();
                } else {
                    // 其他item占一半,也即是1份
                    return 1;
                }
            }
        });
        rvTest.setAdapter(mAdapter);

    }

    class MyAdapter extends RecyclerView.Adapter {

        public static final int TYPE_HEADER = 0;
        public static final int TYPE_FOOTER = 1;
        public static final int TYPE_ITEM = 2;

        @NonNull
        @Override
        public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            if (viewType == TYPE_HEADER) {
                View itemView = LayoutInflater.from(MainActivity.this).inflate(R.layout.header_layout, parent, false);
                return new HeaderViewHolder(itemView);
            } else if (viewType == TYPE_FOOTER){
                View itemView = LayoutInflater.from(MainActivity.this).inflate(R.layout.footer_layout, parent, false);
                return new FooterViewHolder(itemView);
            } else {
                View itemView = LayoutInflater.from(MainActivity.this).inflate(R.layout.item_layout, parent, false);
                return new ItemViewHolder(itemView);
            }
        }

        @Override
        public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
            int viewType = getItemViewType(position);
            if (viewType == TYPE_HEADER) {
                ((HeaderViewHolder) holder).tvHeader.setText("我是header");
            } else if (viewType == TYPE_FOOTER) {
                ((FooterViewHolder) holder).tvFooter.setText("我是footer");
            } else {
                ((ItemViewHolder) holder).tvTest.setText("我是item");
            }
        }

        @Override
        public int getItemCount() {
            return 10;
        }

        @Override
        public int getItemViewType(int position) {
            if (position == 0) {
                return TYPE_HEADER;
            } else if (position == getItemCount()-1) {
                return TYPE_FOOTER;
            } else {
                return TYPE_ITEM;
            }
        }

        class HeaderViewHolder extends RecyclerView.ViewHolder {

            TextView tvHeader;

            public HeaderViewHolder(@NonNull View itemView) {
                super(itemView);
                tvHeader = itemView.findViewById(R.id.tv_test);
            }
        }

        class FooterViewHolder extends RecyclerView.ViewHolder {

            TextView tvFooter;

            public FooterViewHolder(@NonNull View itemView) {
                super(itemView);
                tvFooter = itemView.findViewById(R.id.tv_test);
            }
        }

        class ItemViewHolder extends RecyclerView.ViewHolder {

            TextView tvTest;

            public ItemViewHolder(@NonNull View itemView) {
                super(itemView);
                tvTest = itemView.findViewById(R.id.tv_test);
            }
        }
    }
}

你可能感兴趣的:(RecycleView实现带有section header/footer的多列列表)