问题
I want to achieve multiselect in recyclerview. I have almost got it but it behaves weirdly at times or when there are many items.
I would like to have multiselect function where in on selection I want to change the background color of the item and revert the textcolor of all the text views inside it.
I am facing a weird issue, if I select the 1st record and scroll down then even the 8th record gets selected automatically. And if I select 2nd record then 9th one also gets selected.
Here is the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Models.ViewModels;
using Android.App;
using Android.Content;
using Android.Graphics;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.Widget;
using Android.Views;
using Android.Widget;
namespace A.Droid.Adapters
{
public class DeliveryAdapter : RecyclerView.Adapter//, View.IOnClickListener
{
List<RequestViewModel> list;
public Context v;
public event EventHandler<int> phoneClick;
List<RequestViewModel> selectedList = new List<RequestViewModel>();
public DeliveryAdapter(List<RequestViewModel> records, Context v1)
{
list = records;
v = v1;
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
// Inflate the CardView for the photo:
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.activity_cardview_slinkyRecordList, parent, false);
DeliveryListViewHolder vh = new DeliveryListViewHolder(itemView, OnPhoneClick);
return vh;
}
// Fill in the contents of the photo card (invoked by the layout manager):
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
DeliveryListViewHolder viewHolder = holder as DeliveryListViewHolder;
viewHolder.PICNumber.Text = string.IsNullOrEmpty(list[position].PICNumber) ? "-" : list[position].PICNumber;
viewHolder.PropertyName.Text = string.IsNullOrEmpty(list[position].PropertyName) ? "-" : list[position].PropertyName;
viewHolder.ContactAddress.Text = string.IsNullOrEmpty(list[position].ContactAddress) ? "-" : list[position].ContactAddress;
viewHolder.ContactPerson.Text = string.IsNullOrEmpty(list[position].ContactPerson) ? "-" : list[position].ContactPerson;
viewHolder.ContactNumber.Text = string.IsNullOrEmpty(list[position].ContactNumber) ? "-" : list[position].ContactNumber;
viewHolder.NumberOfAliveSpecies.Text = list[position].NumberOfAliveStock + " Alive " + list[position].NameOfSpecies;
viewHolder.NumberOfDeadSpecies.Text = list[position].NumberOfDeadStock + " Dead " + list[position].NameOfSpecies;
viewHolder.DistanceOfTransporterToPIC.Text = list[position].DistanceOfTransporterFromPIC.ToString() + " KM"; //DeliveryList[position].DistanceOfTransporterFromPIC.ToString();
//viewHolder.MainLinearLayout.SetOnClickListener((new OnClickListener(viewHolder.MainLinearLayout,position)); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
//viewHolder.MainLinearLayout.SetOnClickListener(this); // cardViewList.Add(viewHolder.cardView); //add all the cards to this list
viewHolder.cardView.Click += delegate (object sender, EventArgs e)
{
if (selectedList.All(i => i.slinkyStockRequestId != list[position].slinkyStockRequestId))
{
selectedList.Add(list[position]);
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.PICNumber.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.PropertyName.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactAddress.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactPerson.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.ContactNumber.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.NumberOfAliveSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.NumberOfDeadSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.DistanceOfTransporterToPIC.SetTextColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.mapIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
viewHolder.contactIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
viewHolder.phoneIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.dark_blue), PorterDuff.Mode.SrcAtop);
}
else
{
selectedList.Remove(list[position]);
viewHolder.MainLinearLayout.SetBackgroundColor(v.Resources.GetColor(Resource.Color.dark_blue));
viewHolder.PICNumber.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.PropertyName.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactAddress.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactPerson.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.ContactNumber.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.NumberOfAliveSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.NumberOfDeadSpecies.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.DistanceOfTransporterToPIC.SetTextColor(v.Resources.GetColor(Resource.Color.white));
viewHolder.mapIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
viewHolder.contactIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
viewHolder.phoneIcon.SetColorFilter(v.Resources.GetColor(Resource.Color.white), PorterDuff.Mode.SrcAtop);
}
};
animate(holder);
}
public List<RequestViewModel> GetSelectedItems()
{
return selectedList;
}
// Return the number of photos available in the photo album:
public override int ItemCount
{
get { return list.Count; }
}
// Raise an event when the phone-click takes place:
void OnPhoneClick(int position)
{
if (phoneClick != null)
{
phoneClick(this, position);
}
}
public class DeliveryListViewHolder : RecyclerView.ViewHolder
{
public ImageView MapTag { get; private set; }
public TextView PICNumber { get; private set; }
public TextView PropertyName { get; private set; }
public TextView ContactAddress { get; private set; }
public TextView ContactPerson { get; private set; }
public TextView ContactNumber { get; private set; }
public TextView NameOfSpecies { get; private set; }
public TextView NumberOfAliveSpecies { get; private set; }
public TextView NumberOfDeadSpecies { get; private set; }
public TextView DistanceOfTransporterToPIC { get; private set; }
public CardView cardView { get; private set; }
public LinearLayout MainLinearLayout { get; private set; }
public ImageView mapIcon { get; private set; }
public ImageView contactIcon { get; private set; }
public ImageView phoneIcon { get; private set; }
// Get references to the views defined in the CardView layout.
public DeliveryListViewHolder(View itemView, Action<int> phoneClickListener) : base(itemView)
{
MapTag = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
PICNumber = itemView.FindViewById<TextView>(Resource.Id.PICNumber);
PropertyName = itemView.FindViewById<TextView>(Resource.Id.nameOfProperty);
ContactPerson = itemView.FindViewById<TextView>(Resource.Id.contactPerson);
NumberOfAliveSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfAliveSpecies);
NumberOfDeadSpecies = itemView.FindViewById<TextView>(Resource.Id.noOfDeadSpecies);
DistanceOfTransporterToPIC = itemView.FindViewById<TextView>(Resource.Id.areaInKM);
ContactAddress = itemView.FindViewById<TextView>(Resource.Id.address);
ContactNumber = itemView.FindViewById<TextView>(Resource.Id.mobileNo);
mapIcon = itemView.FindViewById<ImageView>(Resource.Id.mapIcon);
contactIcon = itemView.FindViewById<ImageView>(Resource.Id.contactIcon);
phoneIcon = itemView.FindViewById<ImageView>(Resource.Id.phoneIcon);
cardView = itemView.FindViewById<CardView>(Resource.Id.mainCardviewLayout);
MainLinearLayout = itemView.FindViewById<LinearLayout>(Resource.Id.MainLinearLayout);
ContactNumber.Click += (sender, e) => phoneClickListener(base.Position);
}
}
}
}
回答1:
Your Model should have
private boolean isSelected = false
public boolean isSelected() {
return isSelected;
}
public void setSelected(boolean selected) {
isSelected = selected;
}
in your onClick event,
Note: For Best practice setTag(position) with your position to your view that is getting clicked and use that tag value as a position.
int pos = (int) view.getTag();
list[pos].setSelected(!list[pos].isSelected());
notifyItemChanged(position);
I think this will resolve your problem regarding
I select the 1st record and scroll down then even the 8th record gets selected automatically. And if I select 2nd record then 9th one also gets selected.
Once you will use and operate using position with setTag() this issue of scrolling and position getting selected automatically will be eliminated
回答2:
Add one extra field in your model class
public boolean isSelected = false;
then after in bindViewHolder
manage your check/uncheck view.
if the user clicks on your particular view you have to manage like below code.
list.get(position).setSelected(true);
notifyItemChanged(position);
Here, setSelected()
is a method from your model class.
来源:https://stackoverflow.com/questions/49610629/multiselect-recyclerview