0

私はRecyclerViewに10のビューを保持しています。各ビューはコースを表し、ArrayListに格納されています。各コースには色付けを制御する列挙型「状態」があり、一度に1つのコースだけを選択できるようにしています。これは私が知らないうちに小さな変化を起こし、1日かそれ以上後まで気付かないまで完全に機能しました。Recyclerview onClickは間違った表示を返します

コースをクリックすると、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(); 
    } 
} 

は私の自然な反応は、適切な色を更新するために、フラグメントレベル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

関連する問題