当前位置: 首页 > 知识库问答 >
问题:

RecyclerView项上的事件一次影响多行,而不是一个特定行

刘瀚
2023-03-14

为了总结我的应用程序片段,我有一个大小是动态的,相对于一个变量的ViewModel(当这个变量改变时,RecyclView的项目列表分别增长或收缩)。

每行都有几个按钮。每个按钮上都有一个OnClickListener。(单击时,按钮消失)。

问题:当点击一个按钮时,不仅该按钮消失,而且每增加一个7的倍数(按索引)也消失。

例如:按下第1行中的按钮,第8、15和22行中会发生完全相同的事情,即使只单击了第1行。

我目前正在通过片段的onViewCreated方法将侦听器传递给适配器中的私有侦听器变量(构造函数中的侦听器集)。

我将展示片段和适配器的相关部分:

片段:

public class MyFragment extends Fragment {
    private MyModel model;
    private ArrayList<Data> dataList;
    private int numberOfDataItems;

    private RecyclerView content;
    private RecycleAdapter adapter;

    private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            RecyclerAdapter.ViewHolder viewHolder = (RecyclerAdapter.ViewHolder) view.getTag();

            // This is the buggy bit
            viewHolder.myButton.setVisibility(View.GONE);

            int position = viewHolder.getAdapterPosition();
            Data data = dataList.get(position);
            // TODO: eventually do some logic here with the data
        }
    }

    @Override
    public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
        content = view.findViewById(R.id.content);
        model.createDataList(numberOfDataItems);
        dataList = model.getDataList();

        adapter = new RecycleAdapter(dataList);
        content.setAdapter(adapter);
        content.setLayoutManager(new LinearLayoutManager(getContext()));

        adapter.setOnItemClickListener(onItemClickListener);
    }
}

适配器:

public class RecycleAdapter extends RecyclerView.Adapter<RecycleAdapter.ViewHolder> {
    private List<Data> dataList;
    private View.OnClickListener onItemClickListener;

    public class ViewHolder extends RecyclerView.ViewHolder {
        public Button myButton;

        public ViewHolder(View itemView) {
            super(itemView);

            myButton = itemView.findViewById(R.id.myButton);
            myButton.setTag(this);
            myButton.setOnClickListener(onItemClickListener);
        }
    }

    @Override
    public RecycleAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        Context conext = parent.getContext();
        LayoutInflater inflater = LayoutInflater.from(context);

        View DataView = inflater.inflate(R.layout.data_layout, parent, false);
        return new ViewHolder(dataView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
        Data data = dataList.get(position);
        // Do stuff with data

        myButton.setText(data);
    }

    public void setOnItemClickListener(View.OnClickListener itemClickListener) {
        onItemClickListener = itemClickListener;
    }
}

共有2个答案

夏和雅
2023-03-14

请使用下面的剪子获取准确位置,setTag();转到视图,然后单击time,使用getTag()获取标记值;为了完美的位置。

    myViewHolder.ivVoiceThumb.setTag(pos);
    myViewHolder.ivVoiceThumb.setOnClickListener(view -> {
        int getPos = (int)view.getTag();
    });
宗政文彬
2023-03-14

在执行此操作时,您正在向onClick侦听器传递viewHolder

   myButton.setTag(this);  // this = viewHolder

viewHolder是一个可循环使用的视图。因此,不能将此视图视为唯一的项目视图。请记住,创建viewHolder是为了被其他项目重用。这就是为什么你会在其他项目中看到自己的行动。

解决方案是:

设置为标签,而不是视图夹,而是项目位置。然后,在数据结构中,应该添加变量来记住哪些按钮应该显示或不应该显示。

class Data {
    ...
    String text;
    boolean btnVisible;
}

视图中。OnClickListener您应该设置这些变量的值。

private View.OnClickListener onItemClickLIstener = new View.OnClickListener() {
    @Override
    public void onClick(View view) {
        int position =  (int)view.getTag();
        Data data = dataList.get(position);
        data.btnVisible = false;
        adapter.notifyDataSetChanged();
        // TODO: eventually do some logic here with the data
    }
}

然后,在您的onBindViewHolder中,您应该根据Data结构中的变量设置按钮文本和按钮可见性状态。

@Override
public void onBindViewHolder(@NonNull RecycleAdapter.ViewHolder viewHolder, int position) {
    Data data = dataList.get(position);
    // Do stuff with data

    myButton.setText(data.text);
    myButton.setVisibility(?data.btnVisible:VISIBLE:GONE);
}
 类似资料:
  • 我正在使用一个名为networkx的python包。我在这个包中编写了一些自定义函数。只要我不更新这个包,或者不更改conda环境,它就可以正常工作。但我确信这不是正确的做法。我的问题和这个问题很相似,但我用的是康达。 我想知道我可以使用康达来达到类似的结果吗?“开发模式”是什么意思?它只是这个包的文件夹吗?另外,如果我将它安装在我的项目构建器中,依赖于此包的包会发生什么?当我安装其他一些软件包时

  • 我想在一个POST请求中上传多个图像。目前,我的请求中与文件上传相关的部分正在获取一个文件,如下所示: 这很好用。现在,我尝试更改解码为,并对所有文件执行循环 尝试使用Postman中的参数上传图像时,出现以下错误: 不支持嵌套表单数据解码。 如何解决此问题?

  • fileInput包含一个大约30行的csv文件,我只想访问第二行。 我需要访问第二行而不是第一行(第一行包含列名称)<代码>行[1]给出了

  • 到目前为止,我们主要通过.await来使用 Futures,它将阻塞当前任务,直到特定的Future完成。但是,真正的异步应用程序,通常需要同时执行几个不同的操作。 Executing Multiple Futures at a Time 在本章中,我们将介绍几种,同时执行多个异步操作的方法: join!:等待全部 Futures 完成 select!:等待几种 Futures 之一,完成 Spa

  • 在我的C#/XAML metro应用程序中,有一个启动长时间运行过程的按钮。因此,按照建议,我使用Async/await来确保UI线程不会被阻塞: 偶尔,GetResults中发生的事情需要额外的用户输入才能继续。为了简单起见,假设用户只需单击“Continue”按钮。 我的问题是:如何挂起GetResults的执行,让它等待一个事件,比如单击另一个按钮? 这里有一个丑陋的方法来实现我所寻找的:C

  • 有没有办法运行(不仅编译)单个类(使用main方法)而不是像Intellij IDEA那样运行整个项目? 而且,是否可以在同一窗口中打开不同的项目,而不是在新窗口中或在当前项目的位置打开它们?