【问题标题】:Recyclerview onClick returns wrong viewRecyclerview onClick 返回错误视图
【发布时间】:2017-10-26 10:43:21
【问题描述】:

我有一个RecyclerView,它拥有大约 10 个视图。每个视图代表一门课程,存储在ArrayList 中。每门课程都有一个枚举“状态”,它控制着色并确保一次只能选择一门课程。这很有效,直到我在不知不觉中做了一个小改动,直到一天或更长时间才意识到。

现在,点击课程会导致onClick() 方法接收到错误的视图,通常是向右多 4 或 5 个。点击时RecyclerView不一定会显示此视图,这意味着无法正确更新颜色并导致大问题。

这是片段:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mAdapter = new CoursesAdapter(courseList, context);

    mRecyclerView = (RecyclerView) view.findViewById(R.id.courses_recyclerView);
    RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false);
    mRecyclerView.setLayoutManager(layoutManager);
    mRecyclerView.setAdapter(mAdapter);

    mAdapter.setOnCourseClickListener(new CoursesAdapter.OnCourseClickListener() {
        @Override
        public void onCourseClick(Course course) {
            //TODO when the course is clicked the course will be passed.
            Log.e("TESTING ******", " Course Clicked " + course.name);

            if ( currentCourse!=null) {
                previousSelection = currentCourse;
                previousSelection.setStates(ButtonStates.UNSELECTED);
            }
            currentCourse=course;
            currentCourse.setStates(ButtonStates.SELECTED);

            //refreshCourses();

            //TODO broadcast Course change.
            Intent intent = new Intent(COURSE_SELECTED);
            context.sendBroadcast(intent);
        }

        @Override
        public void onCourseDoubleClick(Course course) {
            //TODO when the course is double clicked the course will be passed.

        }
    });
}

传递给onClick() 的课程总是错误的。状态控制在片段级别完成,因为RecyclerView 适配器有时会将“选定”视图回收到未选定视图。通常,onBindViewHolder() 在选择课程后不会运行,并且由于用于检查按钮状态并更新它们的 switch 语句是在适配器中完成的,因此颜色不会正确更新。

这是适配器:

@Override
public holder onCreateViewHolder(ViewGroup parent, int viewType) {
    //LayoutInflater.from(context).inflate(R.layout.course_layout, parent);


    return new holder(new CourseRaceButton(context));
}

@Override
public void onBindViewHolder(final holder holder, final int position) {

    currentCourse = courses.get(position);

    holder.button.setData(courses.get(position), true);

    if (!initialised) {
         if (position == 0) {
            OnCourseClickListener.onCourseClick(currentCourse);
            selectedCourseView = holder.button;
        }
        initialised = true;
    }

  switch (currentCourse.getStates()) {
        case UNSELECTED:
            holder.button.colourAsDeselected();
            break;
        case SELECTED:

            holder.button.colourAsSelected();
            //selectedCourseView = holder.button;
            break;
    }
}

@Override
public int getItemCount() {
    return courses.size();
}

public interface OnCourseClickListener {
    void onCourseClick(Course course);

    void onCourseDoubleClick(Course course);
}

public class holder extends RecyclerView.ViewHolder implements View.OnClickListener {

    CourseRaceButton button;

    public holder(CourseRaceButton view) {
        super(view);
        view.setOnClickListener(this);
        button = view;

    }

    @Override
    public void onClick(View v) {

        Log.e("TESTING ******", " ON TOUCH COURSE ");

        if (OnCourseClickListener != null) {
            OnCourseClickListener.onCourseClick(currentCourse);
        }
        notifyDataSetChanged();
    }
}

我的自然反应是将notifyDataSetChanged() 放入片段级别onClick() 以便正确更新颜色,但这会给出非法状态异常并且永远不会阻止onClick() 返回错误的路线。

【问题讨论】:

  • 在安卓开发中首先避免枚举...
  • 为什么?虽然不会导致这个特殊问题
  • 检查这个..android.jlelse.eu/…
  • 谢谢,这看起来很有用。我会考虑将来从 Enum 中改变出来。关于为什么 onClick 收到错误视图的任何想法?

标签: android android-fragments android-recyclerview onclicklistener


【解决方案1】:

问题出在您的 onClick() 方法中。您不应该将currentCourse 作为参数传递,因为该变量将存储最后一次回收视图(最后一次调用onBindViewHolder())的过程,而不是您点击的那个。

试试这一行: OnCourseClickListener.onCourseClick(courses.get(getAdapterPosition()));

【讨论】:

  • 好发现!现在完美运行。没想到会尝试,因为它在某些时候可以正常工作。 currentCourse 必须在某个时候正确更新并稍后删除,但这种方式要好得多。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多