我需要在android回收器视图的每个条目中使用复选框来选择一些项目。一旦我选中了位置0的复选框,滚动时每个第9个位置的复选框也会自动选中。
如何克服这个问题?
//在我的适配器类中
_._2
答案 0 :(得分:3)
使用数组保存项目的状态
在适配器中,使用Map或SparseBooleanArray(与map类似,但它是int和boolean的键值对)将所有项目的状态存储在项目列表中,然后在切换检查状态时使用键和值进行比较
在适配器中创建一个SparseBooleanArray
// sparse boolean array for checking the state of the items
private SparseBooleanArray itemStateArray= new SparseBooleanArray();
然后在项目点击处理程序onClick()
中使用itemStateArray中的项目状态在切换之前进行检查,这是一个示例
@Override
public void onClick(View v) {
int adapterPosition = getAdapterPosition();
if (!itemStateArray.get(adapterPosition, false)) {
mCheckedTextView.setChecked(true);
itemStateArray.put(adapterPosition, true);
}
else {
mCheckedTextView.setChecked(false);
itemStateArray.put(adapterPosition, false);
}
}
另外,使用稀疏布尔数组设置绑定视图时的检查状态
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
holder.bind(position);
}
@Override
public int getItemCount() {
if (items == null) {
return 0;
}
return items.size();
}
void loadItems(List<Model> tournaments) {
this.items = tournaments;
notifyDataSetChanged();
}
class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
CheckedTextView mCheckedTextView;
ViewHolder(View itemView) {
super(itemView);
mCheckedTextView = (CheckedTextView) itemView.findViewById(R.id.checked_text_view);
itemView.setOnClickListener(this);
}
void bind(int position) {
// use the sparse boolean array to check
if (!itemStateArray.get(position, false)) {
mCheckedTextView.setChecked(false);}
else {
mCheckedTextView.setChecked(true);
}
}
答案 1 :(得分:1)
您正面临此问题,因为RecyclerView
使用ViewHolder模式,通过该模式可以重用子视图并减少内存消耗。
您可以关注此link
或
您可以按照以下简单步骤进行操作。
1)在数据源中添加一个布尔值,即数据/模型类的列表。
(此布尔值将存储复选框的当前状态)
2)在复选框的onClick
事件中,为呈现的数据模型切换该布尔值,并调用notifyDataSetChanged。
(在此不要使用onCheckedChanged
)
3)在渲染放置条件时,是否基于该布尔值将复选框标记为选中还是未选中。
答案 2 :(得分:1)
如果您可以在一个匿名实现中使用position
,则表示它是final
。就像里面的复选框侦听器一样。
final position
将导致数据和UI之间存在差异,因为将不会再次对其进行定义。
此时,应该在onBindViewHolder
方法上做些细说,这比我的方法有更好的解释。
要获得最终排名,您可以使用:
holder.getAdapterPosition()
您不必担心持有人是否是决赛,因为持有人是该行,并且不会再次被实例化。如果适配器回收了它,那就没问题了。
答案 3 :(得分:1)
当我在OnBindViewHolder中分配了checkedChange侦听器时,我遇到了问题,因此在回收时会多次被调用。对我有用的是在viewHolder create方法中定义回调和侦听器。
public class CheckBoxHolder : RecyclerView.ViewHolder
{
public TextView line, destination, twd;
public ImageView icon;
public LinearLayout lineParent;
public CheckBox checkBox;
public CheckBoxHolder(View view, Action<int, CompoundButton.CheckedChangeEventArgs> listener) : base(view)
{
checkBox = view.FindViewById<CheckBox>(Resource.Id.check_checkBox);
twd = view.FindViewById<TextView>(Resource.Id.check_twd);
destination = view.FindViewById<TextView>(Resource.Id.check_dest);
line = view.FindViewById<TextView>(Resource.Id.check_line);
lineParent = view.FindViewById<LinearLayout>(Resource.Id.check_line_parent);
icon = view.FindViewById<ImageView>(Resource.Id.check_icon);
view.Click += (sender, e) => {
checkBox.Checked = !checkBox.Checked;
};
checkBox.CheckedChange += (object sender, CompoundButton.CheckedChangeEventArgs e) => listener(base.Position, e);
}
}
这是xamarin的C#代码,但该概念应适用于您的问题。