Переключатели теряют значения при прокрутке в RecyclerView - PullRequest
0 голосов
/ 17 апреля 2019

Пожалуйста, помогите мне обнаружить ошибку!Я прочитал множество постов по этому вопросу, но не могу заставить мою работать.Мне кажется, что я делаю это в соответствии с другими решениями, но мне чего-то не хватает.

У меня есть опрос, выполненный в виде вопроса с 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 Ответ

1 голос
/ 17 апреля 2019

Вы можете добавить слушателей к вашей 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;
        }
    }
}
...