RecyclerView网格布局

本文主要介绍了如何在Android中利用RecyclerView的GridLayoutManager来创建网格布局,以解决线性布局扩展性不足的问题。通过定义itemType并填充不同布局,实现动态适配各行的item,从而达到更好的扩展性。

GridLayoutManager

一、 引入问题

在这里插入图片描述

要实现这个布局,我们需要怎么做呢?

  1. 用线性布局画各种长度尺寸的button?
    可行,但扩展性不够,假如将第二行和第三行互换位置呢 再增加几行呢 再增加几种类型的item呢?
  2. 我们可以试下recyclerview的网格布局,进行动态适配各行的item
    可行,扩展性够

二、解决问题

方案:使用recyclerview的网格布局
  1. 定义itemType,针对不同的类型填充不同的布局

这里我们用不同itemType,之后可以在任意位置扩展这些类型的item

  1. 核心代码
public class MainActivity extends AppCompatActivity {
    private RecyclerView mRecyclerView;
    private RecyAdapter mAdapter;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = findViewById(R.id.recycler_view);
        init();
    }

    public void init() {
        GridLayoutManager gridLayoutManager = new GridLayoutManager(getApplicationContext(), 3);
        mRecyclerView.setLayoutManager(gridLayoutManager);
        mAdapter = new RecyAdapter();
        mRecyclerView.setAdapter(mAdapter);
        gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                int itemViewType = mAdapter.getItemViewType(position);
                switch (itemViewType) {
                    case Constant.THREE_COLUME_ITEM_TYPE:
                        return 3;
                    case Constant.TWO_COLUME_ITEM_TYPE:
                        return 2;
                    default:
                        return 1;
                }
            }
        });
        mRecyclerView.addItemDecoration(new RecyclerView.ItemDecoration() {
            @Override
            public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) {
                super.getItemOffsets(outRect, view, parent, state);
                outRect.bottom = 30;
                outRect.left = 30;
            }
        });
    }
}
public class RecyAdapter extends RecyclerView.Adapter {
    private List<Integer> mData = new ArrayList<>();

    public RecyAdapter() {
        mData.add(0);
        mData.add(1);
        mData.add(2);
        mData.add(3);
        mData.add(4);
        mData.add(5);
    }

    @NonNull
    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view;
        int layoutId;
        switch (viewType) {
            case Constant.THREE_COLUME_ITEM_TYPE:
                layoutId = R.layout.item_three_view_layout;
                break;
            case Constant.TWO_COLUME_ITEM_TYPE:
                layoutId = R.layout.item_two_view_layout;
                break;
            default:
                layoutId = R.layout.item_view_layout;
                break;
        }
        view = LayoutInflater.from(parent.getContext()).inflate(layoutId, parent, false);
        return new VH(view);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
        VH vh = (VH) holder;
        vh.mText.setText(mData.get(position) + "");
    }

    @Override
    public int getItemCount() {
        return mData.size();
    }

    @Override
    public int getItemViewType(int position) {
        switch (position) {
            case 0:
                return Constant.THREE_COLUME_ITEM_TYPE;
            case 5:
                return Constant.TWO_COLUME_ITEM_TYPE;
            default:
                return Constant.ONE_COLUME_ITEM_TYPE;
        }
    }

    class VH extends RecyclerView.ViewHolder {
        TextView mText;

        public VH(@NonNull View itemView) {
            super(itemView);
            mText = itemView.findViewById(R.id.text);
        }
    }
}
public class Constant {
    public static final int THREE_COLUME_ITEM_TYPE = 0;
    public static final int ONE_COLUME_ITEM_TYPE = 1;
    public static final int TWO_COLUME_ITEM_TYPE = 2;
}

三、实现效果

在这里插入图片描述

### 如何在 Android RecyclerView 中实现网格布局 #### 设置 `RecyclerView` 基础配置 为了创建一个基于 `RecyclerView` 的网格布局,首先需要设置基础的 XML 和 Java/Kotlin 配置。 XML 文件 (`recyclerview_main.xml`) 定义了一个简单的 `RecyclerView` 控件: ```xml <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerview" android:layout_width="match_parent" android:layout_height="wrap_content"/> ``` 此部分定义了 `RecyclerView` 的基本属性[^1]。 #### 初始化 GridLayoutManager 并应用到 RecyclerView 接着,在 Activity 或 Fragment 中初始化 `GridLayoutManager` 并将其应用于 `RecyclerView`。这可以通过下面的方式完成: ```java // 获取 RecyclerView 实例 RecyclerView recyclerView = findViewById(R.id.recyclerview); // 创建一个新的 GridLayoutManager 对象,并指定列数为 3 GridLayoutManager layoutManager = new GridLayoutManager(this, 3); recyclerView.setLayoutManager(layoutManager); // 将 LayoutManager 应用至 RecyclerView ``` 上述代码片段展示了如何通过编程方式设定 `GridLayoutManager` 来管理 `RecyclerView` 子视图的位置和大小[^2]。 #### 自定义适配器类 为了让 `RecyclerView` 显示数据集的内容,还需要编写自定义的 Adapter 类继承自 `RecyclerView.Adapter`。这里提供了一种简化版的例子作为起点: ```java public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.ViewHolder> { private List<String> dataSet; public static class ViewHolder extends RecyclerView.ViewHolder { TextView textView; public ViewHolder(View itemView) { super(itemView); this.textView = (TextView)itemView.findViewById(R.id.text_view_label); } } @Override public MyRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()) .inflate(R.layout.item_layout, parent, false); return new ViewHolder(view); } @Override public void onBindViewHolder(MyRecyclerViewAdapter.ViewHolder holder, int position) { String text = dataSet.get(position); holder.textView.setText(text); } @Override public int getItemCount() {return dataSet.size();} } ``` 这段代码实现了最基本的适配器逻辑,包括绑定视图持有者以及填充数据集合[^3]。 #### 添加间隔装饰 如果希望给每个网格项之间增加一些空间,则可以利用 `addItemDecoration()` 方法向 `RecyclerView` 添加自定义的 `ItemDecoration` : ```java int spacingInPixels = getResources().getDimensionPixelSize(R.dimen.spacing); recyclerView.addItemDecoration(new SpacesItemDecoration(spacingInPixels)); ``` 这里的 `SpacesItemDecoration` 可以由开发者自行设计来满足特定需求[^4]。 #### 处理点击事件 最后一步是处理用户的交互行为,比如当他们触碰某个列表条目时触发相应的动作。可以在适配器内部监听这些操作: ```java @Override public void onBindViewHolder(final MyRecyclerViewAdapter.ViewHolder holder, final int position){ ... holder.itemView.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v){ Toast.makeText(v.getContext(), "Clicked on item at "+position,Toast.LENGTH_SHORT).show(); } }); } ``` 这样就完成了整个流程——从界面搭建直到功能完善[^5]。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值