在RecyclerView中滚动时,单选按钮会丢失值

时间:2019-04-16 21:18:15

标签: android xamarin android-recyclerview android-viewholder android-radiogroup

请帮助我发现错误!我在这里读过很多关于这个问题的文章,但是我无法工作。在我看来,我正在按照其他解决方案进行操作,但是我缺少了一些东西。

我使用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);
    }
}

1 个答案:

答案 0 :(得分:1)

您可以将侦听器添加到您的 RadioGroup 中,并按如下所示修改适配器:

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;
        }
    }
}