android RecyclerView 简单粗暴设置GridLayoutManager item之间的间距

本文介绍了一种在RecyclerView中实现横向列表和九宫格效果的方法,通过在item布局中添加外层LinearLayout并设置padding来巧妙地实现间距调整,同时提供了GridLayoutManager和StaggeredGridLayoutManager设置Item间距的具体代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近做一个购买会员功能,其中有个RecyclenView 的选择列表,需要实现横向列表,跟九宫格类似的功能。如下图,

其中选择Recyclenview选中变高亮,分分四格就需要给recyclenview 的GridLayoutManager 画分割线,直接画是画不出竖线的,网上看了都说单独处理。然后无意在网上看到一个直接在item中添加一个外层来实现,非常巧妙。

原文

这里是GridLayoutManager或者StaggeredGridLayoutManager 设置Item间距的办法。

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="position"
            type="int" />

        <variable
            name="listener"
            type="com.xxx.listenter.OnRecyclerviewItemClickListener" />

        <variable
            name="buyvip"
            type="com.xxx.response.BuyVipResponse.DataBean.ListBean" />
    </data>

    <!--外层item边距-->
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/lucency_3"
        android:onClick="@{(thenView) ->listener.onItemClickListener(thenView, position)}"
        android:orientation="vertical"
        android:padding="5dp">
        <!--外层item边框-->
        <LinearLayout
            android:id="@+id/vip_item"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@drawable/vip_style"
            android:orientation="vertical">


            <TextView
                android:id="@+id/tv_class"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="10dp"
                android:gravity="center"
                android:text="会员"
                android:textColor="@color/randking_top" />

            <LinearLayout
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginTop="5dp"
                android:gravity="center"
                android:orientation="horizontal">

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:layout_marginLeft="5dp"
                    android:layout_marginRight="3dp"
                    android:gravity="bottom"
                    android:text="¥"
                    android:textColor="@color/randking_top" />

                <TextView
                    android:id="@+id/tv_vip_money"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:gravity="center"
                    android:text="99"
                    android:textColor="@color/randking_top"
                    android:textSize="20sp" />

                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:layout_marginLeft="5dp"
                    android:gravity="bottom"
                    android:text="元"
                    android:textColor="@color/randking_top" />

                <com.gwkj.qixiubaodian.utils.DrawLineTextView
                    android:id="@+id/tv_discount"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="bottom"
                    android:layout_marginLeft="5dp"
                    android:gravity="bottom"
                    android:text="20"
                    android:textColor="@color/gray_99" />

            </LinearLayout>


            <TextView
                android:id="@+id/vip_time"
                style="@style/help_layout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginBottom="10dp"
                android:layout_marginLeft="5dp"
                android:layout_marginRight="5dp"
                android:layout_marginTop="5dp"
                android:ellipsize="end"
                android:gravity="center"
                android:lines="1"
                android:text="7" />

        </LinearLayout>

    </LinearLayout>

</layout>

里面这个RelativeLayout就是你的item正常的布局,而LinearLayout 这个根部局我设置了他的背景色为透明的,再加一个padding就行了,这个padding就是设置item的间距,这样设置item的间距了。

所以说RecyclerView的Item的间距都可以通过item里面设置padding,margin来解决,这种办法相对巧妙。

然后在调用的地方,

int spanCount = 3; // 3 columns
        int spacing = 50; // 50px
        boolean includeEdge = false;
        mRecyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));

如果你了别人的RecycleView 上拉加载下拉刷新,addItemDecoration 这个方法 不一定会给你加上,你可以在源码上自行添加。

public void addItemDecoration(RecyclerView.ItemDecoration decor) {
    mRecyclerView.addItemDecoration(decor,-1);
}

 

### Android RecyclerView Item 显示混乱的原因及解决方案 RecyclerViewItem 显示混乱通常是由于其高效的视图复用机制引发的。具体来说,RecyclerView 会重用已经离开屏幕范围的 View 来减少内存消耗和提升性能。然而,如果没有正确地管理这些被复用的 Views,则可能出现旧数据残留的情况。 以下是几个常见的原因以及对应的解决办法: #### 1. **未在 `onBindViewHolder` 中完全设置所有 UI 属性** 如果只设置了部分属性而忽略了其他可能影响界面展示的部分(比如背景颜色、图标等),那么当这个 ViewHolder 被再次使用时就有可能保留上次使用的那些未更改过的值[^4]。 ```java @Override public void onBindViewHolder(MyViewHolder holder, int position) { User user = userList.get(position); // 完整设定所有的UI组件状态 holder.nameTextView.setText(user.getName()); holder.ageTextView.setText(String.valueOf(user.getAge())); holder.itemView.setBackgroundColor(user.isSelected()? Color.BLUE : Color.WHITE); } ``` #### 2. **缺乏对选中状态的有效控制** 当选定某个项目后改变其外观样式(如高亮显示),如果不小心让该样式的修改作用到了别的非目标项目上就会造成视觉上的错乱现象[^3]。 可以通过引入额外的状态标记变量来跟踪哪些项目已被选中,并据此调整它们的表现形式;同时记得每当绑定新的数据到某一项的时候都要重新评估并应用相应的格式化规则。 ```java private SparseBooleanArray selectedPositions = new SparseBooleanArray(); @Override public void onBindViewHolder(final MyViewHolder holder, final int position){ ... boolean isSelected = selectedPositions.get(position); holder.itemView.setSelected(isSelected); if (isSelected){ holder.itemView.setBackgroundResource(R.color.selected_background); }else{ holder.itemView.setBackgroundResource(android.R.color.transparent); } holder.itemView.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v){ toggleSelection(position); notifyItemChanged(position); } }); } private void toggleSelection(int position){ if(selectedPositions.contains(position)){ selectedPositions.delete(position); }else{ selectedPositions.put(position,true); } } ``` #### 3. **数据源更新后的通知方式不当** 当基础数据发生变化时,应该及时告知 Adapter 进行刷新操作。简单粗暴的方式就是调用 `notifyDataSetChanged()` ,但这会导致整个列表都被重新绘制一遍,效率较低。更推荐的做法是对具体的变动区域单独发出变更信号,例如新增加了一个元素则只需呼叫 `notifyItemInserted(index)` 即可[^4]。 ```java // 正确的数据更新流程示范 public void updateData(List<User> newData){ this.userList.clear(); this.userList.addAll(newData); // 只有在确实有必要的情况下才整体刷新 notifyDataSetChanged(); /* 或者考虑局部刷新 */ /* int startPosition = ... ; // 计算得到起始位置 int itemCount = ... ; // 新增项目的数量 notifyItemRangeInserted(startPosition,itemCount); */ } ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值