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

总结

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

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

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

相关推荐
wk灬丨4 小时前
Android Choreographer 监控应用 FPS
android·kotlin
大胃粥5 小时前
Android U WMS : Activity 冷启动(2) 添加启动窗口
android
魏大橙5 小时前
长亭WAF绕过测试
android·运维·服务器
志尊宝5 小时前
Android 中使用高德地图实现根据经纬度信息画出轨迹、设置缩放倍数并定位到轨迹路线的方法
android
吾爱星辰5 小时前
Kotlin while 和 for 循环(九)
android·开发语言·kotlin
我命由我123455 小时前
Kotlin 极简小抄 P3(函数、函数赋值给变量)
android·开发语言·java-ee·kotlin·android studio·学习方法·android-studio
大风起兮云飞扬丶7 小时前
Android——内部/外部存储
android
niurenwo8 小时前
Android深入理解包管理--记录存储模块
android
文 丰8 小时前
【Android Studio】使用雷电模拟器调试
android·ide·android studio