如何使onclick方法的if else语句中的holder在onbindviewholder方法的参数中没有final in参数viewholder的情况下工作

8cdiaqws  于 2021-07-07  发布在  Java
关注(0)|答案(1)|浏览(286)

当一个按钮与回收器视图中的文本(layoutpasswd)一起定位时,我试图进行文本更改,如果再次按下该按钮,则将其更改回原来的位置。例如密码隐藏按钮。适配器的值来自静态类对象arraylist。现在出现的问题是,recycler视图中所有项的值(仅适用于layoutpasswd)都是相同的。

public void onBindViewHolder(@NonNull final viewHolder holder, int position) {
    holder.layoutUName.setText(users.get(position).getUserName());
    pos = position;
    holder.layoutPasswd.setText("********");
    holder.btnViewChanger.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            if (holder.view1) {
                holder.layoutPasswd.setText(users.get(pos).getPasswd());
                holder.btnViewChanger.setText("hide");
                holder.view1 = false;
            } else {
                holder.layoutPasswd.setText("********");;
                holder.btnViewChanger.setText("Show");
                holder.view1 = true;
            }
        }
      });
hvvq6cgz

hvvq6cgz1#

您不能依赖viewholders或recyclerview中的视图来保持任何状态,因为它们是回收的。每次一个视图滚动到屏幕上,它首先调用 onBindViewHolder 函数更新viewholder的内容以匹配数据。
在中的视图或viewholder示例上设置的任何配置 onBindViewHolder 如果视图从屏幕上滚下,则不能依赖于保持不变,因为原始的viewholder可能会被回收用于某些其他数据,而当它在屏幕上滚回时,您可能会看到从刚刚从屏幕上滚下的其他数据中回收的某个其他视图。
因此,如果您的视图具有要“粘贴”的配置,则必须在更改它时对其进行备份,并在中恢复它 onBindViewHolder . 实现这一点的方式将取决于如何管理传递给适配器的数据。
如果可以修改用户类,则可以添加 Boolean 它存储是否应该显示密码。然后在你的 onBindViewHolder ,则基于此布尔值还原状态。当状态改变时,也会更新这个布尔值。
我还更新了click侦听器的工作方式,以简化切换。我移除了 pos = position 因为几乎可以肯定这不是你应该做的事。

public void onBindViewHolder(@NonNull final viewHolder holder, int position) {
    final User user = users.get(position)
    holder.layoutUName.setText(user.getUserName());
    holder.layoutPasswd.setText(user.isShowPassword() ? user.getPasswd() : "********");
    holder.btnViewChanger.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            user.setShowPassword(!user.isShowPassword());
            holder.layoutPasswd.setText(user.isShowPassword() ? user.getPasswd() : "********");
            holder.btnViewChanger.setText(user.isShowPassword() ? "hide" : "show");
        }
      });

    // ...
}

如果您不能修改用户类,这就更复杂了。那么适配器应该有自己的 ArrayList<Boolean> 按位置索引存储状态,但需要将此列表至少与绑定的数据保持相同的时间,如果刷新了整个数据列表,则将所有内容重置为false。

相关问题