RecyclerView嵌套RecyclerView点击事件遇到取值错乱的问题

其实问题根本就是咱们没有处理好被嵌套的那层recycleview的position

那么解决思路也很简单,想办法把被嵌套的那层recycleview的position传出来即可

上一个简单的效果图:

video2gif_20190304_215107.gif

首先

build.gradle文件添加依赖

dependencies {

api fileTree(dir: 'libs', include: ['*.jar'])

testImplementation 'junit:junit:4.12'

androidTestImplementation 'com.android.support.test:runner:1.0.2'

androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'

api 'com.android.support.constraint:constraint-layout:1.1.3'

api 'com.android.support:appcompat-v7:28.0.0'

//一个是recycleview依赖用的,一个是butterknife大家应该很熟了

api 'com.android.support:design:28.0.0'

api 'com.jakewharton:butterknife:8.5.1'

}

MainActivity布局很简单:

一个RecycleView即可

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginLeft="15dp"

android:layout_marginRight="15dp"

android:orientation="vertical">

android:id="@+id/center_reclycleview"

android:layout_width="match_parent"

android:layout_height="match_parent"/>

然后是外层的item布局:

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:descendantFocusability="blocksDescendants"

android:orientation="vertical">

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:focusable="false"

android:layout_marginTop="5dp"

android:orientation="vertical">

android:id="@+id/tv_title"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:focusable="false"

android:gravity="center"

android:text="xxxx"

android:textColor="@color/GoldenColor"

android:layout_margin="3dp"

android:textSize="14dp" />

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:gravity="center"

android:orientation="vertical">

android:id="@+id/rv_item"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:layout_marginBottom="20dp"/>

第二层:

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:descendantFocusability="blocksDescendants"

android:orientation="vertical">

android:id="@+id/lay_option"

android:layout_width="match_parent"

android:layout_height="35dp"

android:layout_gravity="center"

android:gravity="center"

android:background="@drawable/background_grid_select"

android:orientation="horizontal">

android:id="@+id/tv_option"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:layout_gravity="center"

android:layout_weight="1"

android:gravity="center"

android:text="xxxx"

android:textColor="@color/black"

android:textSize="13dp" />

最主要的来了,外层Adapter:

外层的适配器的话没什么特别的 就是要在里面初始化内层Adapter

public class RvAdapter extends RecyclerView.Adapter {

//新增itemType

public static final int ITEM_TYPE = 100;

private Context mContext;

private List mList;

public RvAdapter(Context context, List list) {

mContext = context;

mList = list;

}

//重写改方法,设置ItemViewType

@Override

public int getItemViewType(int position) {

//返回值与使用时设置的值需保持一致

return ITEM_TYPE;

}

@NonNull

@Override

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detaillist, parent, false);

return new ViewHolder(view);

}

@Override

public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

holder.tv_title.setText(mList.get(position).getTitle());

/*

1.把内部RecyclerView的adapter和集合数据通过holder缓存

2.使内部RecyclerView的adapter提供设置position的方法

*/

holder.list.clear();

holder.list.addAll(mList.get(position).getOptions());

if (holder.mRvAdapter == null) {

//初始化内层adapter时,把对应的position传过去

holder.mRvAdapter = new RvvAdapter(mContext, holder.list, position);

GridLayoutManager layoutManage = new GridLayoutManager(mContext, 2);

holder.rvItemItem.setLayoutManager(layoutManage);

holder.rvItemItem.addItemDecoration(new GridSpacingItemDecoration(2, 20, false));

holder.rvItemItem.setAdapter(holder.mRvAdapter);

} else {

holder.mRvAdapter.setPosition(position);

holder.mRvAdapter.notifyDataSetChanged();

}

}

@Override

public int getItemCount() {

return mList == null ? 0 : mList.size();

}

static class ViewHolder extends RecyclerView.ViewHolder {

@BindView(R.id.tv_title)

TextView tv_title;

@BindView(R.id.rv_item)

RecyclerView rvItemItem;

private RvvAdapter mRvAdapter;

private List list = new ArrayList<>();

ViewHolder(View view) {

super(view);

ButterKnife.bind(this, view);

}

}

}

GridSpacingItemDecoration的话是一个 一个动态设置item个数,间距的工具类

/**

* 重写RecyclerView.ItemDecoration方法

* 一个动态设置item个数,间距的工具类

*/

public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {

private int spanCount; //列数

private int spacing; //间隔

private boolean includeEdge; //是否包含边缘

public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {

this.spanCount = spanCount;

this.spacing = spacing;

this.includeEdge = includeEdge;

}

@Override

public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {

//这里是关键,需要根据你有几列来判断

int position = parent.getChildAdapterPosition(view); // item position

int column = position % spanCount; // item column

if (includeEdge) {

outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)

outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)

if (position < spanCount) { // top edge

outRect.top = spacing;

}

outRect.bottom = spacing; // item bottom

} else {

outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)

outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)

if (position >= spanCount) {

outRect.top = spacing; // item top

}

}

}

}

主要就是内层的Adapter:

这里的话调用了一个MainActivity的公告方法,把对应的tag传出去

public class RvvAdapter extends RecyclerView.Adapter {

private Context mContext;

private List mList;

private int mPosition;

public RvvAdapter(Context context, List list, int position) {

mContext = context;

mList = list;

mPosition = position;

}

/**

* 新增方法

*

* @param position 位置

*/

public void setPosition(int position) {

this.mPosition = position;

}

@NonNull

@Override

public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_detail_option, parent, false);

return new ViewHolder(view);

}

@Override

public void onBindViewHolder(@NonNull ViewHolder holder, int position) {

holder.lay_option.setTag(position);

holder.tvOption.setText(mList.get(position).getDatas());

if (mList.get(position).isSelect()) {

holder.lay_option.setBackgroundResource(R.drawable.background_grid_unselect);

} else {

holder.lay_option.setBackgroundResource(R.drawable.background_grid_select);

}

}

@Override

public int getItemCount() {

return mList == null ? 0 : mList.size();

}

class ViewHolder extends RecyclerView.ViewHolder {

@BindView(R.id.lay_option)

LinearLayout lay_option;

@BindView(R.id.tv_option)

TextView tvOption;

ViewHolder(View view) {

super(view);

ButterKnife.bind(this, view);

//这里设置一个tag,作为被嵌套的recycleview item点击事件的 position

lay_option.setOnClickListener(new View.OnClickListener() {

@Override

public void onClick(View v) {

mList.get((int) v.getTag()).setSelect(true);

((MainActivity) mContext).OnClickListener(mPosition, (int) v.getTag());

}

});

}

}

}

最后就是在MainActivity初始化一些数据,调用即可:

public class MainActivity extends AppCompatActivity {

@BindView(R.id.center_reclycleview)

RecyclerView c_RecyclerView;

private RvAdapter mRvAdapter;

private Bean mBean;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

ButterKnife.bind(this);

initdata();

}

//模拟数据

private void initdata() {

LinearLayoutManager layoutManager = new LinearLayoutManager(this);

layoutManager.setOrientation(LinearLayoutManager.VERTICAL);

c_RecyclerView.setLayoutManager(layoutManager);

c_RecyclerView.setFocusableInTouchMode(false);

mBean = new Bean();

List datas = new ArrayList<>();

//模拟一些数据

for (int i = 0; i < 20; i++) {

Bean.DatasBean datasBean = new Bean.DatasBean();

List option = new ArrayList<>();

Bean.DatasBean.Option optionBean = new Bean.DatasBean.Option();

optionBean.setDatas("这是选项" + i);

option.add(optionBean);

Bean.DatasBean.Option optionBean1 = new Bean.DatasBean.Option();

optionBean1.setDatas("这是选项" + (i + 1));

option.add(optionBean1);

Bean.DatasBean.Option optionBean2 = new Bean.DatasBean.Option();

optionBean2.setDatas("这是选项" + (i + 2));

option.add(optionBean2);

datasBean.setOptions(option);

datasBean.setTitle("这是标题哦1");

datas.add(datasBean);

}

mBean.setDatas(datas);

mRvAdapter = new RvAdapter(this, mBean.getDatas());

c_RecyclerView.setAdapter(mRvAdapter);

mRvAdapter.notifyDataSetChanged();

}

/**

* 设置一个public方法,供adapter点击事件调用

*

* @param position 为第一层recycleview位置

* @param tag 为第二层recycleview位置

*/

public void OnClickListener(int position, int tag) {

final List datasBeans = mBean.getDatas();

for (int i = 0; i < datasBeans.size(); i++) {

if (i == position) {

List option = datasBeans.get(i).getOptions();

for (int j = 0; j < option.size(); j++) {

if (j == tag) {

option.get(j).setSelect(true);

} else {

option.get(j).setSelect(false);

}

}

Toast.makeText(MainActivity.this,

datasBeans.get(position).getTitle() + "-" + option.get(tag).getDatas(),

Toast.LENGTH_SHORT).show();

} else {

//这里让之前选中的效果还原成未选中

List option = datasBeans.get(i).getOptions();

for (int j = 0; j < option.size(); j++) {

option.get(j).setSelect(false);

}

}

}

mRvAdapter.notifyDataSetChanged();

}

}

android view嵌套,Android RecyclerView嵌套RecyclerView点击事件相关推荐

  1. 从源码角度入手实现RecyclerView的Item点击事件

    转载请注明出处:http://www.cnblogs.com/cnwutianhao/p/6758373.html RecyclerView 作为 ListView 和 GridView 的替代产物, ...

  2. Android view.settran,Android RecyclerView从入门到玩坏

    目录 前言 基础使用 分隔线 点击监听 搭配CardView 更丰富的条目 增删条目 快速添加视图 让RecyclerView支持复杂视图 最后前言 RecyclerView在Android界面开发当 ...

  3. Android 高级UI设计笔记20:RecyclerView 的详解之RecyclerView添加Item点击事件

    1. 引言: RecyclerView侧重的是布局的灵活性,虽说可以替代ListView但是连基本的点击事件都没有,这篇文章就来详细讲解如何为RecyclerView的item添加点击事件,顺便复习一 ...

  4. android view禁用,Android 禁止ViewPager的自带滑动效果

    由于最近在做墨水屏的相关工作,ViewPager自带的滑动效果在墨水屏上表现的很不好,残影太重了.所以禁止自带的滑动效果,用接口来接管相关逻辑实现自处理. import android.content ...

  5. Android view变形,android仿变形金刚效果实现MatchView

    what?变形金刚!先看效果吧! MainActivity.javapackage com.lee.matchview; import com.example.matchview.R; import ...

  6. android view 平滑,Android移动view动画问题(让移动更平滑)

    Android写动画效果不是一般的麻烦,网上找了好久,终于解决了动画的问题,总结记录以共勉. 仅以水平方向移动效果做说明,垂直方向类似. 完整动画函数代码: public void slideview ...

  7. android.view.surface,Android SurfaceView 源码分析及使用

    概述 SurfaceView 是 Android 中一种比较特殊的视图(View),它跟平时时候的 TextView.Button 最大的区别是它跟它的视图容器并不是在同一个视图层上,它的 UI 显示 ...

  8. android view flipper,Android之ViewFlipper的简单使用

    大家都使用过ViewPager,但是ViewPager还有一个兄弟,那就是ViewFlipper.两者的名字非常相似,我们可以将ViewPager理解成"一页一页的视图",View ...

  9. android view 曝光,Android 曝光采集(商品view曝光量的统计)第二弹

    安卓端有效曝光统计步骤 1 ,要确定什么样的算有效曝光(在屏幕停留时间超过一个值如2秒) 2,监听到每个view移入和移出屏幕的事件 3,把数据绑定到view(view相当于数据的载体) 4,根据监听 ...

  10. Android 监听多个Spinner 的点击事件

    同一个界面有多个Spinner 点击事件的时候 只有一个onItemSelected 我们可以使用 给不同的点击事件添加Tag 来区分 具体的做法如下: 下面的代码主要体现在添加spinner.set ...

最新文章

  1. qt icon如何显示gif_收集Qt支持的emoji表情-第五弹
  2. Kubernetes数据持久化方案
  3. wpf的tabcontrol获取当前选中的名字_技巧:ANSA中如何快速批量修改PID名字
  4. sql server 2005 32位+64位、企业版+标准版、CD+DVD 下载地址大全
  5. 大型翻车现场?人人车官博辟谣破产传闻 却被群嘲官博怕是还蒙在鼓里
  6. LeetCode 51. N-Queens
  7. jenkins修改pom文件_jenkins参数化配置,pom.xml配置
  8. LeetCode每周刷题(2019.7.1-2019.7.7)
  9. stm32 读取sd卡图片显示_全面测试雷克沙1667x 性能,你懂什么叫超高速SD卡吗
  10. 您应该知道的代码审查工具
  11. FPGA编程入门:Quartus II 设计1位全加器
  12. 【VBA研究】用VBA创建数据透视表
  13. R数据框操作 fourth day
  14. UEBA对抗威胁之“健康就是财富”!
  15. pamac 安装 ros-noetic-desktop-full(AUR) 失败后如何清理残留的问题
  16. 新手如何快速入门IT行业?
  17. 如何找出知乎的所有神回复
  18. web前段网图分类规划
  19. 树莓派串口通信python,【树莓派Pico测评】- AD采集示例及串口通信
  20. 激光测距仪构造原理及激光安全说明——TFN BKD系列双目军绿激光测距测高仪

热门文章

  1. 通信录管理系统--我的第一个C++小程序(源码可用)
  2. QQ四国军棋刷分软件--思路
  3. 京东css3动画全屏海报_京东装修实现全屏CSS3活动海报上下左右抖动动态代码效果,png透明图自动带类似GIF特效 ......
  4. bWKztRpC滞誓麓旁矣驹沤航评旨访司对拥有雷火的宇天,少年也得认真对待:“那好。我
  5. LabVIEW2016安装教程
  6. 微信上传永久图片素材并获取mediaId
  7. RFID户外设备移动巡检智能方案
  8. 【Linux-ARM】电脑 WiFi 上网,开发板与电脑直连
  9. 谷粒商城属性分组功能实现内部包含子组件给父组件数据传递
  10. 生产者消费者问题C++实现