android - 在 RecyclerView 中滚动时,单选按钮会丢失值
问题描述
请帮我找出错误!我已经阅读了很多关于这个问题的帖子,但我无法让我的工作。对我来说,看起来我是根据其他解决方案来做的,但我错过了一些东西。
我有一个使用 recyclerview 实施为一个问题的调查,其中有 3 个可能的答案,其中每一行都有一个带有 3 个单选按钮的单选组。
滚动单选按钮时,它的值会丢失,并且不会在 onbind 事件中再次设置。
public class MyQItem
{
public int Id;
public string Question;
public int Value;
public MyQItem(int id, string question)
{
Id = id;
Question = question;
}
}
internal class MyQFormAdapter : RecyclerView.Adapter
{
private MyQItem[] mDataSource;
public MyQFormAdapter(MyQItem[] mDataSource)
{
this.mDataSource = mDataSource;
}
public override int ItemCount => mDataSource.Length;
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
MyQViewHolder vh = holder as MyQViewHolder;
vh.QuestionId.Text = mDataSource[position].Id.ToString();
vh.Question.Text = mDataSource[position].Question;
vh.Button1.CheckedChange -= Button1_CheckedChange;
vh.Button2.CheckedChange -= Button2_CheckedChange;
vh.Button3.CheckedChange -= Button3_CheckedChange;
vh.Button1.Checked = mDataSource[position].Value == 1;
vh.Button2.Checked = mDataSource[position].Value == 2;
vh.Button3.Checked = mDataSource[position].Value == 3;
vh.Button1.Tag = position;
vh.Button2.Tag = position;
vh.Button3.Tag = position;
vh.Button1.CheckedChange += Button1_CheckedChange;
vh.Button2.CheckedChange += Button2_CheckedChange;
vh.Button3.CheckedChange += Button3_CheckedChange;
}
void Button1_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e) => SetChecked((RadioButton)sender, 1, e.IsChecked);
void Button2_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e) => SetChecked((RadioButton)sender, 2, e.IsChecked);
void Button3_CheckedChange(object sender, CompoundButton.CheckedChangeEventArgs e) => SetChecked((RadioButton)sender, 3, e.IsChecked);
void SetChecked(RadioButton btn, int value, bool isChecked)
{
if (!isChecked)
return;
var position = (int)btn.Tag;
mDataSource[position].Value = value;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.MyQItemLayout, parent, false);
MyQViewHolder vh = new MyQViewHolder(itemView);
return vh;
}
}
[Activity(Label = "MyQEditActivity")]
public class MyQEditActivity : Activity
{
MyQItem[] mDataSource = new MyQItem[] {
new MyQItem(1, "Lorem Ipsum"),
new MyQItem(2, "Lorem Ipsum"),
new MyQItem(3, "Lorem Ipsum"),
new MyQItem(4, "Lorem Ipsum"),
new MyQItem(5, "Lorem Ipsum"),
new MyQItem(6, "Lorem Ipsum"),
new MyQItem(7, "Lorem Ipsum"),
new MyQItem(8, "Lorem Ipsum"),
new MyQItem(9, "Lorem Ipsum"),
new MyQItem(10, "Lorem Ipsum"),
new MyQItem(11, "Lorem Ipsum"),
new MyQItem(12, "Lorem Ipsum"),
};
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.MyQEditLayout);
var recyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);
recyclerView.SetLayoutManager(new LinearLayoutManager(this));
recyclerView.SetAdapter(new MyQFormAdapter(mDataSource));
}
}
public class MyQViewHolder : RecyclerView.ViewHolder
{
public TextView QuestionId { get; private set; }
public TextView Question { get; private set; }
public RadioButton Button1 { get; private set; }
public RadioButton Button2 { get; private set; }
public RadioButton Button3 { get; private set; }
public MyQViewHolder(View itemView) : base(itemView)
{
QuestionId = itemView.FindViewById<TextView>(Resource.Id.MyQuestionId);
Question = itemView.FindViewById<TextView>(Resource.Id.MyQuestion);
Button1 = itemView.FindViewById<RadioButton>(Resource.Id.noButton);
Button2 = itemView.FindViewById<RadioButton>(Resource.Id.someButton);
Button3 = itemView.FindViewById<RadioButton>(Resource.Id.yesButton);
}
}
解决方案
您可以将侦听器添加到您的RadioGroup并像这样修改您的适配器:</p>
class MyQFormAdapter : RecyclerView.Adapter, RadioGroup.IOnCheckedChangeListener
{
private MyQItem[] mDataSource;
public MyQFormAdapter(MyQItem[] mDataSource)
{
this.mDataSource = mDataSource;
}
public override int ItemCount => mDataSource.Length;
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
MyQViewHolder vh = holder as MyQViewHolder;
// cancel the listener to prevent RadioGroup from displaying confusing key codes
vh.Group.SetOnCheckedChangeListener(null);
vh.Group.ClearCheck();
vh.Group.Tag = position;
switch (mDataSource[position].Value)
{
case 1:
vh.Group.Check(Resource.Id.noButton);
break;
case 2:
vh.Group.Check(Resource.Id.someButton);
break;
case 3:
vh.Group.Check(Resource.Id.yesButton);
break;
}
vh.QuestionId.Text = mDataSource[position].Id.ToString();
vh.Question.Text = mDataSource[position].Question;
vh.Group.SetOnCheckedChangeListener(this);
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.MyQItemLayout, parent,false);
MyQViewHolder vh = new MyQViewHolder(itemView);
return vh;
}
public class MyQViewHolder : RecyclerView.ViewHolder
{
public TextView QuestionId { get; private set; }
public TextView Question { get; private set; }
public RadioGroup Group { get; private set; }
public MyQViewHolder(View itemView) : base(itemView)
{
QuestionId = itemView.FindViewById<TextView>(Resource.Id.MyQuestionId);
Question = itemView.FindViewById<TextView>(Resource.Id.MyQuestion);
Group = itemView.FindViewById<RadioGroup>(Resource.Id.radiogroup);
}
}
public void OnCheckedChanged(RadioGroup @group, int checkedId)
{
switch (checkedId)
{
case Resource.Id.noButton:
mDataSource[(int) @group.Tag].Value = 1;
break;
case Resource.Id.someButton:
mDataSource[(int)@group.Tag].Value = 2;
break;
case Resource.Id.yesButton:
mDataSource[(int)@group.Tag].Value = 3;
break;
}
}
}
推荐阅读
- javascript - 带有 HTML5 Canvas 的 TypeScript 3.9 - .strokeStyle 上的错误
- python - 您可以将函数返回的值保存为单独的变量吗?
- python - Z标签方向随着更多字符而反转matplotlib 3D Plot
- react-native - 如何在 onFocus 事件中获取 React Native TextInput 的垂直偏移量?
- excel - 当您在单元格中时运行宏?
- java - 我们如何使用 Retryable
- django-rest-framework - 如何将 API 密钥头注入 Django REST API 测试
- javascript - 从绘制边缘修复折线图
- google-cloud-platform - Syncinc 处的 Google Cloud Build/App 引擎错误
- split - 在 Informatica 中将平面文件字符串拆分为多列