0

저는 10 시가 넘는보기를 보유하고있는 RecyclerView입니다. 각보기는 코스를 나타내며 ArrayList에 저장됩니다. 각 코스에는 색칠을 제어하고 한 번에 하나의 코스 만 선택할 수있는 enum "State"가 있습니다. 이것은 무의식적으로 작은 변화가 생길 때까지 완벽하게 작동했으며, 하루 이상이 경과 할 때까지는 깨닫지 못했습니다.Recyclerview onClick 잘못된보기를 반환합니다.

이제 코스를 클릭하면 onClick() 메서드가 잘못된보기 (대개 4 또는 5가 오른쪽 방향)를 수신하게됩니다. 이보기는 클릭 할 때 RecyclerView에 의해 반드시 표시되지는 않습니다. 따라서 색칠이 올바르게 업데이트되지 않고 큰 문제가 발생합니다. 탐색 과정은 onClick()에 전달 항상 잘못

@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. 

     } 
    }); 
} 

:

는 여기에 조각입니다. 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(); 
    } 
} 

내 자연 반응이 제대로 색상을 업데이트하기 위해 조각 수준 onClick()notifyDataSetChanged()을 넣어하지만, 그 illegalState 예외를 제공하고 잘못된 과정을 반환하는 onClick()을 멈추지 않을 것 .

+0

첫 피하기 열거 ... –

+0

를? – Richardweber32

+0

이 특정 문제를 일으키지는 않을 것입니다 .https : //android.jlelse.eu/android-performance-avoid-using-enum-on-android-326be0794dc3 –

답변

1

문제는 onClick() 방법에 있습니다. currentCourse을 매개 변수로 전달해서는 안되며, 그 변수는 마지막으로 재생 된 뷰 (마지막 호출은 onBindViewHolder())를 저장하는 것이므로 사용자가 클릭 한 변수가 아닙니다.

대신이 줄을보십시오 : 어떤 이유로 andoid 개발 OnCourseClickListener.onCourseClick(courses.get(getAdapterPosition()));

+0

잘 찾아 냈습니다! 완벽하게 작동합니다. 그것을 어느 시점에서 올바르게 작동했기 때문에 시도하지 않았을 것입니다. currentCourse는 어느 시점에서 제대로 업데이트되어 나중에 제거되어야합니다. 그러나이 방법이 훨씬 좋습니다. 고맙습니다 – Richardweber32

관련 문제