Android RecyclerView 实现 GridView ,并实现点击效果及方向位置的显示
效果图
一、引入
implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.30'
二、使用步骤
1.Adapter
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 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.应用
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();
总结
如果对你有所帮助的话,不妨 点赞收藏
如果你有什么疑问的话,不妨 评论私信
青山不改,绿水长流 ,有缘江湖再见 ~