Recyclerview onClick返回错误的视图

时间:2017-10-26 10:43:21

标签: android android-fragments android-recyclerview onclicklistener

我有一个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()返回错误的路线。

1 个答案:

答案 0 :(得分:2)

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

请尝试使用此行: OnCourseClickListener.onCourseClick(courses.get(getAdapterPosition()));