更改一个 ViewHolder 项目也会影响到其他项目
Changing one ViewHolder item also affects to other items
我有一个基于 RecyclerView 的简单 mp3 播放器。
有一个 Adapter 和 ViewHolder 用于处理播放列表中的曲目。
public class TracksAdapter extends RecyclerView.Adapter<TracksAdapter.ViewHolder> {
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cell_playlist, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.trackName.setText("Track " + position);
}
@Override
public int getItemCount() {
return tracks.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
final TextView trackName;
ViewHolder(View itemView) {
super(itemView);
trackName = itemView.findViewById(R.id.trackName);
}
}
}
当我点击曲目时,我想更改播放列表中所选曲目的背景颜色。问题是当我将背景颜色设置为一个项目时,它会影响到播放列表中的每十分之一单元格。
例如,如果播放列表中有 100 首曲目,则将突出显示 10 首曲目,包括所选曲目。
方法 findViewHolderForAdapterPosition(position) returns 带有选定轨道的 ViewHolder。
private void setTrackColor(int position) {
RecyclerView.ViewHolder holder =
recyclerView.findViewHolderForAdapterPosition(position);
if (holder == null) return;
View item = holder.itemView;
item.setBackgroundColor(ContextCompat.getColor(main, R.color.playing));
}
您不能直接更改视图的颜色。在RecyclerView
中,所有Views
都被重新使用。所以,如果你改变一个位置的颜色,你可能会间接改变其他位置的颜色,因为相同的视图将被重新使用。
您必须单独保存当前播放曲目的位置。这样,在 onBindViewHolder
期间,您可以检查当前正在绑定的视图是否是当前正在播放的曲目。如果是同一首曲目,请应用一些颜色。如果不是同一种颜色,恢复默认颜色
public class TracksAdapter extends RecyclerView.Adapter<TracksAdapter.ViewHolder> {
private int mTrackPlaying = -1;
public void setTrackPlaying(int position) {
mTrackPlaying = position;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.trackName.setText("Track " + position);
if(position == mTrackPlaying) {
holder.itemView.setBackgroundColor(ContextCompat.getColor(main, R.color.playing));
} else {
// Here, you must restore the color because the view is reused.. so, you may receive a reused view with wrong colors
holder.itemView.setBackgroundColor(ContextCompat.getColor(main, R.color.NOT_playing));
}
}
}
然后
private void setTrackColor(int position) {
TracksAdapter adapter = (TracksAdapter) recyclerView.getAdapter();
adapter.setTrackPlaying(position);
// Line below will `RecyclerView` to re-draw that position.. in other words, it will triggers a call to `onBindViewHolder`
adapter.notifyItemChanged(position);
// Reset the color of song previously playing..
adapter.notifyItemChanged(oldPosition);
}
我有一个基于 RecyclerView 的简单 mp3 播放器。 有一个 Adapter 和 ViewHolder 用于处理播放列表中的曲目。
public class TracksAdapter extends RecyclerView.Adapter<TracksAdapter.ViewHolder> {
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cell_playlist, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.trackName.setText("Track " + position);
}
@Override
public int getItemCount() {
return tracks.size();
}
class ViewHolder extends RecyclerView.ViewHolder {
final TextView trackName;
ViewHolder(View itemView) {
super(itemView);
trackName = itemView.findViewById(R.id.trackName);
}
}
}
当我点击曲目时,我想更改播放列表中所选曲目的背景颜色。问题是当我将背景颜色设置为一个项目时,它会影响到播放列表中的每十分之一单元格。
例如,如果播放列表中有 100 首曲目,则将突出显示 10 首曲目,包括所选曲目。
方法 findViewHolderForAdapterPosition(position) returns 带有选定轨道的 ViewHolder。
private void setTrackColor(int position) {
RecyclerView.ViewHolder holder =
recyclerView.findViewHolderForAdapterPosition(position);
if (holder == null) return;
View item = holder.itemView;
item.setBackgroundColor(ContextCompat.getColor(main, R.color.playing));
}
您不能直接更改视图的颜色。在RecyclerView
中,所有Views
都被重新使用。所以,如果你改变一个位置的颜色,你可能会间接改变其他位置的颜色,因为相同的视图将被重新使用。
您必须单独保存当前播放曲目的位置。这样,在 onBindViewHolder
期间,您可以检查当前正在绑定的视图是否是当前正在播放的曲目。如果是同一首曲目,请应用一些颜色。如果不是同一种颜色,恢复默认颜色
public class TracksAdapter extends RecyclerView.Adapter<TracksAdapter.ViewHolder> {
private int mTrackPlaying = -1;
public void setTrackPlaying(int position) {
mTrackPlaying = position;
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
holder.trackName.setText("Track " + position);
if(position == mTrackPlaying) {
holder.itemView.setBackgroundColor(ContextCompat.getColor(main, R.color.playing));
} else {
// Here, you must restore the color because the view is reused.. so, you may receive a reused view with wrong colors
holder.itemView.setBackgroundColor(ContextCompat.getColor(main, R.color.NOT_playing));
}
}
}
然后
private void setTrackColor(int position) {
TracksAdapter adapter = (TracksAdapter) recyclerView.getAdapter();
adapter.setTrackPlaying(position);
// Line below will `RecyclerView` to re-draw that position.. in other words, it will triggers a call to `onBindViewHolder`
adapter.notifyItemChanged(position);
// Reset the color of song previously playing..
adapter.notifyItemChanged(oldPosition);
}