Android RecyclerView 实现 GridView ,并实现点击效果及方向位置的显示

效果图


一、引入

复制代码
 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'

二、使用步骤

1.Adapter

java 复制代码
public class UnAdapter extends BaseQuickAdapter<UnBean.ResultBean, BaseViewHolder> {

    private int selectedPosition = RecyclerView.NO_POSITION; // 用于记录当前选中的位置
    private int lastSelectedPosition = RecyclerView.NO_POSITION; // 上一次选中的位置

    private int spanCount = 4; // 每行显示的列数

    // 处理item点击事件的方法
    public void onItemClick(int position) {
        // 如果点击的是当前选中的item,则不执行任何操作(或者执行特定的操作)
        if (position == selectedPosition) {
            return;
        }

        // 更新选中状态
        if (selectedPosition != RecyclerView.NO_POSITION) {
            // 如果之前有选中的item,先通知适配器刷新它,以恢复默认背景
            notifyItemChanged(selectedPosition);
        }

        // 更新选中位置
        lastSelectedPosition = selectedPosition;
        selectedPosition = position;

        // 通知适配器刷新新选中的item
        notifyItemChanged(selectedPosition);
    }

    // (可选)如果需要,可以添加一个方法来处理取消选中item的情况
    private void deselectItem(int position) {
        if (position == selectedPosition) {
            selectedPosition = RecyclerView.NO_POSITION;
        }
    }

    public  UnAdapter(int layoutResId, @Nullable List<UnBean.ResultBean> data) {
        super(layoutResId, data);
    }

    @SuppressLint("ResourceAsColor")
    @Override
    protected void convert(BaseViewHolder helper, UnBean.ResultBean item) {

        ImageView fx_rightImg = helper.getView(R.id.fx_right_img);
        ImageView fx_leftImg = helper.getView(R.id.fx_left_img);
        LinearLayout fx_upLayout = helper.getView(R.id.fx_up_layout);
        LinearLayout bgLayout = helper.getView(R.id.bg_layout);


        // 根据是否选中来设置背景
        if (helper.getLayoutPosition() == selectedPosition) {
          bgLayout.setBackgroundResource(R.drawable.shape_blue_8);
            helper.setTextColor(R.id.cd_tv, mContext.getColor(R.color.white));
        } else if (helper.getLayoutPosition() == lastSelectedPosition && lastSelectedPosition != RecyclerView.NO_POSITION) {
           bgLayout.setBackgroundResource(R.drawable.shape_bg_position_sel);
            helper.setTextColor(R.id.cd_tv, mContext.getColor(R.color.blue_text));
        } else {
           bgLayout.setBackgroundResource(R.drawable.shape_bg_position_sel);
            helper.setTextColor(R.id.cd_tv, mContext.getColor(R.color.blue_text));
        }

        // 设置点击监听器(注意:这里应该在ViewHolder的构造函数中设置,以避免重复设置)
        // 但为了简化示例,这里直接在convert中设置(不推荐)
       bgLayout.setOnClickListener(v -> {
            onItemClick(helper.getPosition());
        });

        // 计算当前项位于哪一行
        int position = helper.getAdapterPosition(); // 获取当前项的索引
        int row = position / spanCount; // 整数除法得到当前行号(注意:这里假设没有头部或脚部项)
        // 计算当前项在当前行的列索引(从0开始)
        int column = position % spanCount;
        // 判断是否是每行的首项
        boolean isFirstItemInRow = column == 0;

        // 判断是否是每行的尾项
        // 注意:这里的判断需要考虑是否是最后一行且不是整除spanCount的情况
        boolean isLastItemInRow = (position + 1) % spanCount == 0 || position == getItemCount() - 1;

        // 或者更精确地判断尾项(仅当当前项不是最后一行的唯一项时才需要额外检查)
        boolean isLastItemInRowPrecise = (position + 1) % spanCount == 0 ||
                (position == getItemCount() - 1 && position % spanCount != spanCount - 1);

        // 判断当前项是否为列表中的最后一位
        boolean isLastItemInList = position == getItemCount() - 1;

        // 判断行数的奇偶性
        if (row % 2 == 0) {
            fx_rightImg.setVisibility(View.VISIBLE);
            if (isFirstItemInRow) {
                fx_upLayout.setVisibility(View.GONE);
            }
            if (isLastItemInRowPrecise) {
                fx_upLayout.setVisibility(View.VISIBLE);
                fx_rightImg.setVisibility(View.GONE);
            }
        } else {
            fx_leftImg.setVisibility(View.GONE);
            fx_rightImg.setVisibility(View.VISIBLE);
            fx_upLayout.setVisibility(View.GONE);
            if (isFirstItemInRow) {
                fx_upLayout.setVisibility(View.VISIBLE);
            }
            if (isLastItemInRowPrecise) {
                fx_upLayout.setVisibility(View.GONE);
                fx_leftImg.setVisibility(View.GONE);
            }
        }
        // 根据是否为最后一位的逻辑来设置UI
        if (isLastItemInList) {
            fx_upLayout.setVisibility(View.GONE);
            fx_rightImg.setVisibility(View.GONE);
        }
        helper.setText(R.id.cd_tv, item.getTrain());
    }


}

2. item_layout.xml

XML 复制代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="@dimen/dimen_120"
    android:layout_height="@dimen/dimen_80"
    android:layout_marginLeft="@dimen/dimen_15"
    android:orientation="vertical"
    android:padding="@dimen/dimen_5">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:orientation="horizontal">

        <LinearLayout
            android:id="@+id/bg_layout"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center">

            <TextView
                android:id="@+id/cd_tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="G2519"
                android:textColor="@color/c_3681ff" />

        </LinearLayout>

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:gravity="center">

            <ImageView
                android:id="@+id/fx_right_img"
                android:layout_width="@dimen/dimen_15"
                android:layout_height="@dimen/dimen_15"
                android:background="@drawable/icon_fx_right"
                android:visibility="gone" />

            <ImageView
                android:id="@+id/fx_left_img"
                android:layout_width="@dimen/dimen_15"
                android:layout_height="@dimen/dimen_15"
                android:background="@drawable/icon_fx_left"
                android:visibility="gone" />


        </LinearLayout>


    </LinearLayout>

    <LinearLayout
        android:id="@+id/fx_up_layout"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_40"
        android:gravity="center_vertical"
        android:visibility="gone">

        <ImageView
            android:layout_width="@dimen/dimen_15"
            android:layout_height="@dimen/dimen_15"
            android:layout_marginLeft="@dimen/dimen_25"
            android:background="@drawable/icon_fx_up" />
    </LinearLayout>


</LinearLayout>

3.应用

java 复制代码
 fromAssets = ReadAsUtil.getFromAssets(this, "UnList.json");
 unBean = new Gson().fromJson(fromAssets, UnBean.class);
 unList = unBean.getResult();
 gridLayoutManager = new GridLayoutManager(this, 4);
 cdLv.setLayoutManager(gridLayoutManager);
 unAdapter = new UnAdapter(R.layout.item_layout, unList);
 cdLv.setAdapter(unAdapter);
 unAdapter.notifyDataSetChanged();

总结

如果对你有所帮助的话,不妨 点赞收藏

如果你有什么疑问的话,不妨 评论私信

青山不改,绿水长流 ,有缘江湖再见 ~

相关推荐
薛晓刚4 分钟前
MySQL的replace使用分析
android·adb
DengDongQi27 分钟前
Jetpack Compose 滚轮选择器
android
stevenzqzq28 分钟前
Android Studio Logcat 基础认知
android·ide·android studio·日志
代码不停36 分钟前
MySQL事务
android·数据库·mysql
朝花不迟暮41 分钟前
使用Android Studio生成apk,卡在Running Gradle task ‘assembleDebug...解决方法
android·ide·android studio
yngsqq1 小时前
使用VS(.NET MAUI)开发第一个安卓APP
android·.net
Android-Flutter1 小时前
android compose LazyVerticalGrid上下滚动的网格布局 使用
android·kotlin
Android-Flutter1 小时前
android compose LazyHorizontalGrid水平滚动的网格布局 使用
android·kotlin
千里马-horse1 小时前
RK3399E Android 11 将自己的库放到系统库方法
android·so·设置系统库
美狐美颜sdk1 小时前
Android直播美颜SDK:选择指南与开发方案
android·人工智能·计算机视觉·第三方美颜sdk·视频美颜sdk·人脸美型sdk