RecyclerView OnClick在其他位置更改项目

时间:2018-07-09 14:11:00

标签: android xamarin android-recyclerview xamarin.android recycler-adapter

我在RecyclerView中有一个字符串列表。我需要能够单击列表中的项目,并将背景更改为黄色。我可以单击一个项目并更改背景,但是当我向下滚动列表时,看到列表中的另一个项目的背景也变成了黄色吗?

我尝试了许多不同的方法来实现这一目标。我尝试设置一个接口,并在ViewHolder等中单击。

我的代码在下面。

活动:

[Activity(Label = "PregnancyListActivity")]
public class PregnancyListActivity : Activity
{
    RecyclerView mRecyclerView;
    RecyclerView.LayoutManager mLayoutManager;
    PregnantAnimalAdapter mAdapter;

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        SetContentView(Resource.Layout.PregnancyListLayout);

        mRecyclerView = FindViewById<RecyclerView>(Resource.Id.recyclerView);

        // Plug in the linear layout manager:
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.SetLayoutManager(mLayoutManager);

        // Plug in my adapter:
        mAdapter = new PregnantAnimalAdapter();
        mAdapter.ItemClick += MAdapter_ItemClick;
        mRecyclerView.SetAdapter(mAdapter);
    }
}

视图架

[Activity(Label = "PregnantAnimalViewHolder")]
public class PregnantAnimalViewHolder : RecyclerView.ViewHolder
{
    public LinearLayout mBackground { get; private set; }
    public TextView mAnimalTag { get; private set; }

    public PregnantAnimalViewHolder(View itemView) : base(itemView)
    {
        // Locate and cache view references:
        mBackground = itemView.FindViewById<LinearLayout>(Resource.Id.pregnancyBackground);
        mAnimalTag = itemView.FindViewById<TextView>(Resource.Id.animalTag);

    }
}

适配器:

public class PregnantAnimalAdapter : RecyclerView.Adapter
{
public PregnantAnimalAdapter pregnantAnimalAdapter;
public List<PregAnimals> mAnimals;

public PregnantAnimalAdapter()
{
    mAnimals = new List<PregAnimals>{
        new PregAnimals("111", false),
        new PregAnimals("112", false),
        new PregAnimals("113", false),
        new PregAnimals("114", false),
        new PregAnimals("115", false),
        new PregAnimals("221", false),
        new PregAnimals("222", false),
        new PregAnimals("223", false),
        new PregAnimals("224", false),
        new PregAnimals("225", false),
        new PregAnimals("331", false),
        new PregAnimals("332", false),
        new PregAnimals("333", false),

        new PregAnimals("444", false),
        new PregAnimals("443", false),
        new PregAnimals("554", false),
        new PregAnimals("4435", false),
        new PregAnimals("4234", false),
        new PregAnimals("543", false),
        new PregAnimals("3452", false),
        new PregAnimals("3321", false),
        new PregAnimals("6676", false),
        new PregAnimals("4367", false)
    };
}

public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
    View itemView = LayoutInflater.From(parent.Context).
                                  Inflate(global::RecordMilk.Resource.Layout.PregnancyItem, parent, false);

    PregnantAnimalViewHolder vh = new PregnantAnimalViewHolder(itemView);

    vh.mBackground.Click += (object sender, EventArgs e) => {
        mAnimals[vh.LayoutPosition].Preg = true;
    };

    return vh;
}



public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    PregnantAnimalViewHolder vh = holder as PregnantAnimalViewHolder;

    vh.mAnimalTag.Text = mAnimals[position].Tag;
    if (mAnimals[position].Preg == true)
    {
        vh.mBackground.SetBackgroundResource(RecordMilk.Resource.Color.munster_yellow);
    }

}



public override int ItemCount
{
    get { return mAnimals.Count; }
}
}

public class PregAnimals
{
    public string Tag { get; set; }
    public bool Preg { get; set; }

    public PregAnimals(string tag, bool preg)
    {
        Tag = tag;
        Preg = preg;
    }

}

对于为什么不将其设置在列表中,我感到非常困惑。任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:0)

问题在于RecyclerView在做应做的事情-回收视图。更改了颜色的视图正在重新用于新项目,但其颜色仍处于选中状态。

假设您要保留选择内容,则需要跟踪选择了哪个选项,然后在OnBindViewHolder中将背景色设置为选定或未选定的颜色。否则,只需将背景设置为未选中即可。

此外,您可以只创建一个StateListDrawable并将其分配给具有选中/未选中状态的背景,因此您要做的就是将视图的状态设置为selected。优点是可以将所有样式保留在资源中。

public class PregnantAnimalViewHolder : RecyclerView.ViewHolder
{
    public LinearLayout mBackground { get; private set; }
    public TextView mAnimalTag { get; private set; }
    public bool Selected {get;set;}
    public int position {get;set;}

    public PregnantAnimalViewHolder(View itemView) : base(itemView)
    {
        // Locate and cache view references:
        mBackground = itemView.FindViewById<LinearLayout>(Resource.Id.pregnancyBackground);
        mAnimalTag = itemView.FindViewById<TextView>(Resource.Id.animalTag);

    }
}

然后在OnBindViewHolder中

public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
    PregnantAnimalViewHolder vh = holder as PregnantAnimalViewHolder;

    vh.mAnimalTag.Text = mAnimals[position];
    vh.position = position;
    vh.View.SetBackgroundResource(
         vh.Selected?Resource.Color.munster_yellow:Resource.Color.whatever);

    // or vh.View.SetSelected(vh.Selected) for using StateListDrawable as the background

}

答案 1 :(得分:0)

尝试在适配器中添加此行:

@Override
public int getItemViewType(int position) {
    return position; 
}