[英]RecyclerView marks unselected items as selected
My RecyclerView repeats the marked item on Scrolling.我的 RecyclerView 在滚动上重复标记的项目。
My RecyclerView has 10 Lines which are actually displayed!我的 RecyclerView 有 10 行实际显示! If I click on the first, its background gets highlighted.
如果我点击第一个,它的背景会突出显示。 If I scroll down now, another item is highlighted!
如果我现在向下滚动,则会突出显示另一个项目!
If I scroll up, the first items isn't highlighted anymore, but another item...如果我向上滚动,第一个项目不再突出显示,而是另一个项目......
Here's an Image of the Problem:这是问题的图像:
Any my RecyclerViewAdapter:任何我的 RecyclerViewAdapter:
public class SelectSongRecyclerViewAdapter extends RecyclerView.Adapter<SelectSongRecyclerViewAdapter.Holder> {
private Song[] sSongs;
private List<Song> selectedSongs;
public SelectSongRecyclerViewAdapter(Song[] songs) {
sSongs = songs;
selectedSongs = new ArrayList<>();
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_selectsongsview, parent, false);
Holder holder = new Holder(view);
return holder;
}
@Override
public void onBindViewHolder(final Holder holder, final int position) {
//holder.imvSong.setImageResource(R.drawable.standardartwork);
holder.txvSongTitle.setText(sSongs[position].getTitle());
holder.txvSongInfo.setText(sSongs[position].getArtists());
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedSongs.contains(sSongs[position])) {
selectedSongs.remove(sSongs[position]);
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
selectedSongs.add(sSongs[position]);
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
}
});
}
@Override
public int getItemCount() {
return sSongs != null ? sSongs.length : 0;
}
public Song[] getSelectedSongs() {
Song[] songs = new Song[selectedSongs.size()];
return selectedSongs.toArray(songs);
}
public class Holder extends RecyclerView.ViewHolder {
LinearLayout linearLayout;
ImageView imvSong;
TextView txvSongTitle;
TextView txvSongInfo;
public Holder(View layout) {
super(layout);
linearLayout = (LinearLayout) layout;
imvSong = (ImageView) layout.findViewById(R.id.imvSong);
txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle);
txvSongInfo = (TextView) layout.findViewById(R.id.adap_txvSongInfo);
}
}
}
I hope you can help me!我希望你能帮助我! Thanks!
谢谢!
Here my working Code I used!这是我使用的工作代码!
When onBindViewHolder is called, the items are only selected if they are in the selectedSongs
-List!当 onBindViewHolder 被调用时,只有在
selectedSongs
-List 中的项目才会被selectedSongs
!
@Override
public void onBindViewHolder(final Holder holder, int position) {
holder.txvSongTitle.setText(sSongs[position].getTitle());
holder.txvSongInfo.setText(sSongs[position].getArtists());
if (!selectedSongs.contains(sSongs[position])) {
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int pos = holder.getAdapterPosition();System.out.println(sSongs[pos].getTitle());
if (selectedSongs.contains(sSongs[pos])) {
selectedSongs.remove(sSongs[pos]);
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
selectedSongs.add(sSongs[pos]);
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
}
});
}
This is how RecyclerView works: - creates as many Views can fit inside the screen and each time you scroll passes the view to onBindViewHolder in order to update it's data based on the item index这就是 RecyclerView 的工作原理: - 创建尽可能多的视图可以容纳在屏幕内,每次滚动时将视图传递给 onBindViewHolder 以便根据项目索引更新它的数据
Now when one of the views is clicked you change the background color of the view and when you scroll you pass a view with backgroundColor (colorItemSelected) and just change it's data.现在,当单击其中一个视图时,您会更改视图的背景颜色,当您滚动时,您会传递一个带有 backgroundColor (colorItemSelected) 的视图并更改它的数据。
What you should do is onBindViewHolder set view's background color to colorItemSelected if item is selected OR transparent if not.您应该做的是 onBindViewHolder 将视图的背景颜色设置为 colorItemSelected 如果项目被选中或透明如果没有。
Here is some co这是一些合作
public void onBindViewHolder(final Holder holder, final int position) {
//holder.imvSong.setImageResource(R.drawable.standardartwork);
holder.txvSongTitle.setText(sSongs[position].getTitle());
holder.txvSongInfo.setText(sSongs[position].getArtists());
if (selectedSongs.contains(sSongs[position])) {
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}else {
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedSongs.contains(sSongs[position])) {
selectedSongs.remove(sSongs[position]);
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
selectedSongs.add(sSongs[position]);
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
}
});
}
try this adapter,试试这个适配器,
public class SelectSongRecyclerViewAdapter extends RecyclerView.Adapter<SelectSongRecyclerViewAdapter.Holder> {
private Song[] sSongs;
private List<Song> selectedSongs;
public SelectSongRecyclerViewAdapter(Song[] songs) {
sSongs = songs;
selectedSongs = new ArrayList<>();
}
@Override
public Holder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.adapter_selectsongsview, parent, false);
Holder holder = new Holder(view);
return holder;
}
@Override
public void onBindViewHolder(final Holder holder, final int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
return sSongs != null ? sSongs.length : 0;
}
public Song[] getSelectedSongs() {
Song[] songs = new Song[selectedSongs.size()];
return selectedSongs.toArray(songs);
}
public class Holder extends RecyclerView.ViewHolder implements View.OnClickListener {
LinearLayout linearLayout;
ImageView imvSong;
TextView txvSongTitle;
TextView txvSongInfo;
public Holder(View layout) {
super(layout);
linearLayout = (LinearLayout) layout;
imvSong = (ImageView) layout.findViewById(R.id.imvSong);
txvSongTitle = (TextView) layout.findViewById(R.id.adap_txvSongtitle);
txvSongInfo = (TextView) layout.findViewById(R.id.adap_txvSongInfo);
linearLayout.setOnClickListener(this);
}
public void bind(int position){
txvSongTitle.setText(sSongs[position].getTitle());
txvSongInfo.setText(sSongs[position].getArtists());
if (selectedSongs.contains(sSongs[getAdapterPosition()])) {
linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
}
@Override
public void onClick(View v) {
if (selectedSongs.contains(sSongs[getAdapterPosition()])) {
selectedSongs.remove(sSongs[getAdapterPosition()]);
holder.linearLayout.setBackgroundResource(android.R.color.transparent);
}
else {
selectedSongs.add(sSongs[getAdapterPosition()]);
holder.linearLayout.setBackgroundResource(R.color.colorItemSelected);
}
}
}
} }
Change you onBindViewHolder to this将您的 onBindViewHolder 更改为此
@Override
public void onBindViewHolder(final Holder holder, final int position) {
//holder.imvSong.setImageResource(R.drawable.standardartwork);
holder.txvSongTitle.setText(sSongs[position].getTitle());
holder.txvSongInfo.setText(sSongs[position].getArtists());
holder.linearLayout.setBackgroundResource(selectedSongs.contains(sSongs[position]) ? R.color.colorItemSelected : android.R.color.transparent);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (selectedSongs.contains(sSongs[position])) {
selectedSongs.remove(sSongs[position]);
notifyDataSetChanged();
}
else {
selectedSongs.add(sSongs[position]);
notifyDataSetChanged();
}
}
});
}
Java爪哇
private int position = -1;
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
holder.itemView.setSelected(holder.getLayoutPosition() == this.position);
holder.itemView.setOnClickListener(v -> {
holder.itemView.setSelected(true);
this.position = holder.getLayoutPosition();
});
}
Kotlin科特林
val position = -1
fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
holder.itemView.isSelected = holder.layoutPosition == this.position
holder.itemView.setOnClickListener { v: View? ->
holder.itemView.isSelected = true
this.position = holder.layoutPosition
}
}
item_background.xml item_background.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_selected="true">
<shape>
<solid android:color="@android:color/holo_blue_bright" />
</shape>
</item>
<item>
<shape>
<solid android:color="@android:color/white" />
</shape>
</item>
</selector>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.