2016-06-21 3 views
1

Я пытаюсь выделить реализацию списка, например, когда пользователь нажимает на строку, ее фон меняет цвет. Приложение работает нормально, но когда я просматриваю список вверх и вниз, в то время как одна строка подсвечивается, неожиданно выделяются и другие строки. Ниже приведено тестовое приложение, показывающее это поведение (код основан на http://inducesmile.com/android/how-to-set-recycleview-item-row-background-color-in-android/).RecycleView подсвечивает неправильную строку (Android)

Главная Деятельность

public class MainActivity extends AppCompatActivity { 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    RecyclerView recyclerView = (RecyclerView)findViewById(R.id.recycler_view); 
    LinearLayoutManager layoutManager = new LinearLayoutManager(MainActivity.this); 
    recyclerView.setLayoutManager(layoutManager); 

    List<ItemObject> posts = returnListItems(); 

    RecyclerViewAdapter adapter = new RecyclerViewAdapter(MainActivity.this, posts); 
    recyclerView.setAdapter(adapter); 
} 

private List<ItemObject> returnListItems(){ 
    List<ItemObject> items = new ArrayList<ItemObject>(); 
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016")); 
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016")); 
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016")); 
    items.add(new ItemObject("Cheerleader", "OMI", "2016")); 
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016")); 
    items.add(new ItemObject("Hello", "Adele", "2016")); 
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016")); 
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016")); 
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016")); 
    items.add(new ItemObject("Cheerleader", "OMI", "2016")); 
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016")); 
    items.add(new ItemObject("Hello", "Adele", "2016")); 
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016")); 
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016")); 
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016")); 
    items.add(new ItemObject("Cheerleader", "OMI", "2016")); 
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016")); 
    items.add(new ItemObject("Hello", "Adele", "2016")); 
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016")); 
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016")); 
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016")); 
    items.add(new ItemObject("Cheerleader", "OMI", "2016")); 
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016")); 
    items.add(new ItemObject("Hello", "Adele", "2016")); 
    items.add(new ItemObject("Blank Space", "Taylor Swift", "2016")); 
    items.add(new ItemObject("Uptown Funk", "Mark Ronson", "2016")); 
    items.add(new ItemObject("Can't Feel My Face", "The Weeknd", "2016")); 
    items.add(new ItemObject("Cheerleader", "OMI", "2016")); 
    items.add(new ItemObject("What Do You Mean?", "Justin Bieber", "2016")); 
    items.add(new ItemObject("Hello", "Adele", "2016")); 
    return items; 
} 

RecyclerViewHolders

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

public TextView songTitle; 
public TextView songYear; 
public TextView songAuthor; 

private static int selectedPos = -1; 
private static View selectedView = null; 

public RecyclerViewHolders(View itemView) { 
    super(itemView); 
    itemView.setOnClickListener(this); 
    songTitle = (TextView)itemView.findViewById(R.id.song_title); 
    songYear = (TextView)itemView.findViewById(R.id.song_year); 
    songAuthor = (TextView)itemView.findViewById(R.id.song_author); 
} 

@Override 
public void onClick(View view) { 
    int position = getAdapterPosition(); 
    if (selectedPos == position){  // deselect the row 
     selectedView.setSelected(false); 
     selectedPos = -1; // no selected row 
    }else { 
     if (selectedPos != -1) 
      selectedView.setSelected(false);   // deselect the row 
     selectedView = view; 
     selectedPos = position; 
     selectedView.setSelected(true); 
    } 
} 
} 

RecyclerViewAdapter

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewHolders>{ 

private List<ItemObject> itemList; 

public RecyclerViewAdapter(Context context, List<ItemObject> itemList) { 
    this.itemList = itemList; 
} 

@Override 
public RecyclerViewHolders onCreateViewHolder(ViewGroup parent, int viewType) { 
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, null); 
    return new RecyclerViewHolders(layoutView); 
} 

@Override 
public void onBindViewHolder(RecyclerViewHolders holder, int position) { 
    holder.songTitle.setText("" + position + " Song Title: " + itemList.get(position).getSongTitle()); 
    holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear()); 
    holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor()); 
} 

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

ItemObject

public class ItemObject { 

private String songTitle; 
private String songYear; 
private String songAuthor; 

public ItemObject(String songTitle, String songYear, String songAuthor) { 
    this.songTitle = songTitle; 
    this.songYear = songYear; 
    this.songAuthor = songAuthor; 
} 

public String getSongTitle() { 
    return songTitle; 
} 

public String getSongYear() { 
    return songYear; 
} 

public String getSongAuthor() { 
    return songAuthor; 
} 
} 
+0

Вы отправили полный код 'RecyclerViewHolders'? Я не вижу, как инициализируется 'selectedView'. – jaibatrik

+0

Инициализируется в onClick() после выбора строки (изначально она установлена ​​в нуль) - см. Строку 'selectedView = view' – Zvi

ответ

1

Это потому, что в Recycler View вид получает переработаны. Это означает, что один и тот же вид снова используется для отображения других элементов. Поэтому, когда другой вид начинает использовать тот же вид, который был выбран, он начинает показывать неверные результаты.

Для того, чтобы исправить это, вам необходимо внести изменения в свой код onBindViewHolder. Что-то вроде ниже:

@Override 
    public void onBindViewHolder(RecyclerViewHolders holder, int position) { 
     View view = holder.getView(); //Please check the appropriate function which returns the "itemView" from view holder. 
     if(position == holder.getSelectedPosition()) //Add a getter method for selected position 
     { 
      view.setSelected(true); 
     } 
     else { 
      view.setSelected(false); 
     } 

     holder.songTitle.setText("" + position + " Song Title: " + itemList.get(position).getSongTitle()); 
     holder.songYear.setText("Song Year: " + itemList.get(position).getSongYear()); 
     holder.songAuthor.setText("Song Author: " + itemList.get(position).getSongAuthor()); 
    } 
+0

Спасибо @Aprit Ratan. Это сработало. Отсутствует «функция» - View view = holder.itemView; – Zvi

+0

Я рад, что это помогло :) –

Смежные вопросы