这是我的代码
@Override
public void onBindViewHolder(final RecyclerViewHolder holder, int position) {
final Songs songs = arrayList.get(position);
holder.favorite.setChecked(songs.getFavorite()); // this line makes me confusing.
holder.favorite.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
int r = db.update_favorite(b,songs.getTitle(),songs.getArtist());
compoundButton.setChecked(b);
}
});
}
这里的问题是我是否包含此代码
holder.favorite.setChecked(songs.getFavorite());
到 onBindViewHolder ,当我更改切换按钮的状态并向下滚动然后向上滚动时,切换按钮的状态会自行更改为原始状态。为了澄清,当切换按钮状态从false变为true并且用户向下和向上滚动时,切换按钮会自动变为原始状态,即为false。
即使用户向下滚动,如何使切换按钮保持状态的变化?请帮帮我。
答案 0 :(得分:3)
这是我的猜测:CompoundButton.OnCheckedChangeListener
在你没想到的时候开火。
想象一下,你有100首歌曲,每首歌曲都不是最喜欢的。您激活与歌曲#5相关联的CompoundButton
,它会触发其OnCheckedChangeListener
并将歌曲#5标记为您数据库中的收藏夹。然后向下滚动,直到歌曲#5不再出现在屏幕上。
在某些时候,之前与歌曲#5相关联的ViewHolder
将被回收,然后重新用于显示另一首歌曲。在那个时间点,将调用onBindViewHolder()
。这将触发这一行:
holder.favorite.setChecked(songs.getFavorite());
请注意,此ViewHolder
曾与歌曲#5相关联,因此在此行开始前CompoundButton
已检查。由于新歌不是收藏,因此该行更改 CompoundButton
以便取消选中。
这将触发onCheckedChangeListener
。除此时,侦听器尚未重新分配,因此仍然引用歌曲#5。由于CompoundButton
已从选中更改为未选中状态,因此聆听者会将第5首歌曲标记为不数据库中的收藏夹。
然后重新分配听众,现在引用新歌。但在这一点上,损害已经完成。
您只需添加
即可解决此问题holder.favorite.setOnCheckedChangeListener(null);
在onBindViewHolder()
的开头。
答案 1 :(得分:0)
Ben P.很好地解释了问题的原因。只是想在解决方案中添加一些东西。
监听 click 事件,而不是监听交换机上的检查更改事件。在交换机上,可以基于多种其他原因触发检查事件。但是只有在用户单击开关时,才会触发单击。
希望我能够正确地解释这些事情。
谢谢。
答案 2 :(得分:0)
还为适配器添加了以下方法后,它为我解决了
@Override
public int getItemViewType(int position) {
return position;
}