【问题标题】:RecyclerView - a single selection selects every 10 rowRecyclerView - 每 10 行选择一次
【发布时间】:2016-11-10 18:04:21
【问题描述】:

这很奇怪,但是当我使用我的代码长按某一行时,该行上的星星变成金色(这是我想要的),而且每颗星星相隔十行。 这是我的代码:

    public class MyViewHolder extends RecyclerView.ViewHolder {
    public TextView localeDisplay;
    private static final int grey_blue = 0xff546E7A;
    private static final int gold = 0xffffa000;

    public MyViewHolder(final View view) {
        super(view);
        localeDisplay = (TextView) view.findViewById(R.id.languageText);

        view.setOnClickListener(new View.OnClickListener() {

                                    @Override
                                    public void onClick(View view) {
                                        Languages currentLanguages = languagesList.get(getAdapterPosition());
                                        Snackbar snackbar;
                                        snackbar = Snackbar.make(view, currentLanguages.getLocaleDisplay() + " selected", Snackbar.LENGTH_INDEFINITE)
                                                .setAction("Next", new View.OnClickListener() {
                                                    @Override
                                                    public void onClick(View v) {
                                                        Intent intent = new Intent(v.getContext(), MainActivity.class);
                                                        v.getContext().startActivity(intent);
                                                    }
                                                });
                                        View snackBarView = snackbar.getView();
                                        snackBarView.setBackgroundColor(grey_blue);
                                        snackbar.show();
                                    }
                                }

        );

        view.setOnLongClickListener(new View.OnLongClickListener()

                                    {
                                        @Override
                                        public boolean onLongClick(View v) {
                                            Toast.makeText(v.getContext(), "Position is " + getAdapterPosition(), Toast.LENGTH_SHORT).show();

                                            ImageView star = (ImageView) view.findViewById(R.id.imageView);

                                            if (star.getColorFilter() == null) {
                                                star.setColorFilter(gold);
                                            } else star.clearColorFilter();

                                            return true;
                                        }
                                    }

        );
    }

我曾尝试关注this tutorial,但发生了同样的行为。 有什么想法可以纠正这个问题吗?

【问题讨论】:

  • 视图正在被回收,这意味着它将被重用而不是重新创建。如果您将星星设置为一个,当它被重复使用时,仍然会设置开始。您需要为每个项目单独设置一个标志,以确定它是否应该设置星标。 set 意思是把它变成金色。
  • 感谢您的回复,但对于动态更改的列表,这可能吗?如果是这样,我会尝试弄清楚如何做到这一点。
  • 您只需要一种方法将列表中的每个特定项目标记为单击或未单击。例如,如果您在列表中设置了第 9 项,则需要说明单击第 9 项的内容。有很多方法可以解决这个问题。适配器只是认识到它是一个可用于您想要做的事情的视图。它不关心视图的当前状态是什么。
  • 感谢您的快速回复! :)

标签: android android-studio onclick android-recyclerview


【解决方案1】:

在您的适配器构造函数中,只需添加此部分:

setHasStableIds(true).

然后覆盖适配器类中的以下方法。

 @Override
   public long getItemId(int position) {
      return position;
   }

 @Override
  public int getItemViewType(int position) {
     return position;
  }

【讨论】:

  • adapter.setHasStableIds(true); (在 rv.setAdapter(adapter) 之前的活动/片段中;
【解决方案2】:

似乎您的视图正在被回收,这意味着您的侦听器引用正在被所有回收的视图调用。

解决这个问题的一个简单方法是在 onBindViewHolder 方法中为每个视图设置新的引用。通常 Viewholder 用于查找视图并保留回收视图的引用,在其中设置数据不是一个好主意。

您可以更改以下视图:

public ExampleViewHolder(View view) {
        super(view);
        myContainer = (LinearLayout) view.findViewById(R.id.myContainer);
        localeDisplay = (TextView) view.findViewById(R.id.languageText);
        star = (ImageView) view.findViewById(R.id.imageView);
    }

并在 onBindViewHolder 处设置监听器:

@Override
public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {

    ExampleHolder holder = (ExampleHolder) viewHolder;

    //Insert the position reference
    holder.myContainer.setTag(position);

    // Setting listeners
    holder.myContainer.setOnClickListener(this);
    holder.myContainer.setOnLongClickListener(this); 

}

然后在您的适配器上实现 OnLongClickListener 和 OnClickListener。

@Override
public boolean onLongClick(View v) {

    //Getting position
    int position = (int)v.getTag();

    //Insert your code
    return false;
}

@Override
public void onClick(View v) {
    //code here
}

如果可行,请给我回信。祝你好运。

【讨论】:

  • 非常感谢您!我正在努力让它工作,但我会很快再试一次。 :)
  • 问题是我有 View myView = view.findViewById(R.id.recycler_view);但“视图”无法解决。我不知道该怎么办。
  • 尝试引用布局容器。 (例如 LinearLayout myContainer = (LinearLayout) view.findViewById(R.id.myContainer);)不要忘记设置监听器对 myContainer 的引用。
  • 我用上面的评论编辑了答案,以及如何插入和获取位置参考。
  • 干杯!非常感谢您的帮助!
【解决方案3】:

这是因为您将获得所有具有R.id.imageView id 的项目。做你想做的事,你需要抓住被点击的项目,只改变所选行的颜色;

【讨论】:

  • 非常感谢,但我认为情况并非如此。 ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-04
  • 2022-09-27
  • 1970-01-01
相关资源
最近更新 更多