如何使单个选择在嵌套的回收器视图中工作



对于我们的应用程序,我必须实现一个嵌套的RecyclerView。我正在从 JSON 中获取表列表,每个表都有另一个列表,其中包含每个表中的组。我可以按照要求在屏幕上获取所有内容,问题是选择。

我在屏幕上有 2 个不同的回收器视图,我似乎无法在这种环境中获得单个选择,尤其是在滚动之后。每个组和每个表都有一个切换按钮,一次只能有一个处于活动状态。

这就是主屏幕的样子

到目前为止,我已经尝试在模型上放置一个布尔值是选择的,但这根本没有奏效。我想出的最接近的解决方案是一个帮助程序类,它搜索屏幕上的每个 CompoundButton,并在选择一个时取消选择它们。问题是这个帮助程序类无法获取屏幕外的按钮。

我如何填充 ParentAdapter (在 MainActivity 中(:

public void setAdapter(List<Table> tableList)
{
RecyclerView recycler_view_parent = findViewById(R.id.recyclerparent);
LinearLayoutManager manager=new LinearLayoutManager(MainActivity.this);
manager.setOrientation(LinearLayoutManager.HORIZONTAL);
recycler_view_parent.setLayoutManager(manager);
recycler_view_parent.setHasFixedSize(true);
recycler_view_parent.setItemViewCacheSize(tableList.size());
ParentAdapter parentAdapter=new ParentAdapter(tableList,MainActivity.this);
recycler_view_parent.setAdapter(parentAdapter);
}

我如何填充 ChildAdapter (在 ParentAdapter 的 onBindViewHolder 中(:

FlexboxLayoutManager manager = new FlexboxLayoutManager(context);
manager.setFlexDirection(FlexDirection.COLUMN);
manager.setJustifyContent(JustifyContent.FLEX_START);
manager.setFlexWrap(FlexWrap.WRAP);
manager.setAlignItems(AlignItems.BASELINE);
holder.recycler_view_child.setLayoutManager(manager);
holder.recycler_view_child.setHasFixedSize(true);
adapter = new ChildAdapter(tableList, tableList.get(position).getGroups(), context);
holder.recycler_view_child.setAdapter(adapter);

所需的输出一次只能切换 1 个表或组(总共,而不是每个回收器视图中的一个(,并且滚动/设备旋转后的状态应相同(。

在过去的几天里,我在这个主题上做了很多研究,我似乎找不到嵌套的RecyclerView的工作示例,在两个RV上都进行了单一选择。

那么有人知道如何解决这个问题吗?我认为最大的问题是告诉家长孩子中的按钮被切换了,反之亦然。

我认为对于父适配器,它应该看起来像这样:

@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, final int position) {
final Table table = tablelist.get(position);
ViewHolder viewHolder = (ViewHolder) holder;
if (table.isTableSelected()) {
viewHolder.toggletable.setChecked(true);
lastToggled = position;
} else {
viewHolder.toggletable.setChecked(false);
}
viewHolder.toggletable.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if (b) {
table.setTableSelected(true);
// notify ChildAdapter and group.setGroupSelected(false)
if (lastToggled >= 0) {
tablelist.get(lastToggled).setTableSelected(false);
// notify ChildAdapter and group.setGroupSelected(false)
notifyItemChanged(lastToggled);
}
lastToggled = position;
} else {
table.setTableSelected(false);
}
}
});
}

提前谢谢。

更新:设法自己提出了一个解决方案,尽管 100% 确定,但不是最好的方法。

首先,实现Greenrobots EventBus:

implementation 'org.greenrobot:eventbus:3.1.1'

现在,在您持有两个回收器视图的活动中注册事件侦听器:

@Override
protected void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}

并订阅 2 种方法。一个用于父事件,一个用于子事件。此方法将在每次选择项目时触发!

@Subscribe(threadMode = ThreadMode.MAIN)
public void onParentEventClicked(ParentAdapter.ParentEvent event) {
// to access the inner adapter here you must set it to public in the ParentAdapter(public ChildAdapter adapter;)
adapter.adapter.deSelectChild();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onChildEventClicked(ChildAdapter.ChildEvent event) {
// normal ParentAdapter reference(ParentAdapter adapter;)
adapter.deSelectParent();
}

在 ParentAdapter 中创建一个方法来取消选择所有父项和一个静态类来触发事件:

public void deSelectParent()
{
for (int i=0;i<data.size();i++)
{
data.get(i).setSelected(false);
}
notifyDataSetChanged();
}
public static class ParentEvent {
View view;
int position;
}

在 ChildAdapter 中,创建一个方法来取消选择所有子项和一个静态类来触发事件:

public void deSelectChild()
{
for (int i=0;i<data.size();i++)
{
datachild.get(i).setSelected(false);
}
notifyDataSetChanged();
}
public static class ChildEvent {
View view;
int position;
}

现在,在 BindViewHolder 上的父项和子项中,模型都需要类似的逻辑:

if (item.isSelected()) {
holder.yourbutton.setChecked(true);
} else {
holder.yourbutton.setChecked(false);
}
holder.yourbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
ParentEvent event = new ParentEvent();
event.view = holder.yourbutton;
event.position = position;
EventBus.getDefault().post(event);
if (holder.yourbutton.isChecked()) {
for (int i = 0; i < data.size(); i++) {
data.get(i).setSelected(false);
}
data.get(position).setSelected(true);
} else {
data.get(position).setSelected(false);
}
notifyDataSetChanged();
}
});

差不多就是这样,每次单击ParentProject都会触发ChildAdapter的取消选择方法,反之亦然。 由于 notifyDataSetChanged(( 的使用率很高,我建议使用此行来摆脱闪烁:

recycler_view_parent.setItemAnimator(null);

任何问题请告诉我!

最新更新