1

我正在使用 DiffUtils 来更新我的 Recyclerview。视觉上有效,但单击一个项目会将其返回给我一个与我单击的项目不匹配的位置

我使用了能够解决位置问题的 NotifyDataChange。但从视觉上看,最后一项配置错误。

我尝试使用能够解决位置问题的 NotifyDataChange。但从视觉上看,最后一项配置错误。

我的适配器:

class AdapterUser : RecyclerView.Adapter
    {
        //Global Var
        public event EventHandler<int> ItemClick;
        public List<Class.Result> ClassUser;
        public Android.Content.Context context;


    public class UserViewHolder : RecyclerView.ViewHolder
    {
        public static TextView txtName { get; set; }
        public static TextView txtEspecialidade { get; set; }

        public static CircleImageView Imagem { get; set; }

        public static Bitmap bitmap { get; set; }

        public static CircleImageView status { get; set; }

        public static Button button { get; set; }

        public UserViewHolder(View itemview, Action<int> listener) : base(itemview)
        {
            UserViewHolder.txtName = itemview.FindViewById<TextView>(Resource.Id.nameUser);
            UserViewHolder.txtEspecialidade = itemview.FindViewById<TextView>(Resource.Id.speciality);
            UserViewHolder.Imagem = itemview.FindViewById<CircleImageView>(Resource.Id.avatarUser);
            UserViewHolder.status = itemview.FindViewById<CircleImageView>(Resource.Id.status);
            UserViewHolder.button = itemview.FindViewById<Button>(Resource.Id.BtCriar);

        }
    }

    public AdapterUser(List<Class.Result> user)
    {
        ClassUser = user;
    }

    public override int ItemCount
    {
        get { return ClassUser.Count(); }
    }



    public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
    {
        //Method to transform the uri to bitmap
        async Task MyMethodAsync()
        {
            // Do asynchronous work.
            UserViewHolder.Imagem.SetImageBitmap(await Droid.Class.Functions.GetImageBitmapFromUrlAsync(ClassUser[position].PhotoUri));
        };

        UserViewHolder userHolder = holder as UserViewHolder;
        if (ClassUser[position].PhotoUri != null)
        {
            MyMethodAsync();
        }
        else
        {
            UserViewHolder.Imagem.SetImageResource(Resource.Drawable.avatar);
        }

        if (ClassUser[position].IsOnline != true)
        {
            UserViewHolder.status.Visibility = ViewStates.Invisible;
        }
        else
        {
            UserViewHolder.status.Visibility = ViewStates.Visible;
        }

        UserViewHolder.txtName.Text = ClassUser[position].Name;
        UserViewHolder.txtEspecialidade.Text = ClassUser[position].Specialty;

        UserViewHolder.button.Click += (sender, args) =>
        {
              Toast.MakeText(context, ClassUser[position].Name, ToastLength.Short).Show();
            Console.WriteLine(ClassUser[position].Name);
        };
    }

    public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
    {
        View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.ResultUser, parent, false);
        UserViewHolder vh = new UserViewHolder(itemView, OnClick);

        context = parent.Context;

        return vh;
    }


    private void OnClick(int obj)
    {

    }


    public void Update(List<Class.Result> oldList, List<Class.Result> newList) 
    {
        // Set detectMoves to true for smoother animations
        MyDiffCallback callback = new MyDiffCallback(oldList, newList);
        DiffUtil.DiffResult result = DiffUtil.CalculateDiff(callback);

        this.ClassUser.Clear();
        this.ClassUser.AddRange(newList);


        // Despatch the updates to your RecyclerAdapter
        result.DispatchUpdatesTo(this);

    }

我的困难:

class MyDiffCallback  : DiffUtil.Callback
{
    List<Class.Result> newList;
    List<Class.Result> oldList;

    public MyDiffCallback(List<Class.Result> oldList, List<Class.Result> newList)
    {
        this.oldList = oldList;
        this.newList = newList;
    }

    public override int NewListSize => newList.Count;

    public override int OldListSize => oldList.Count;

    public override bool AreContentsTheSame(int oldItemPosition, int newItemPosition)
    {
        return oldList[oldItemPosition].IsOnline == newList[newItemPosition].IsOnline;
    }

    public override bool AreItemsTheSame(int oldItemPosition, int newItemPosition)
    {
        return oldList[oldItemPosition].RowKey == newList[newItemPosition].RowKey;
    }

    public override Java.Lang.Object GetChangePayload(int oldItemPosition, int newItemPosition)
    {
        return base.GetChangePayload(oldItemPosition, newItemPosition);
    }


}

我的活动:

ClassUtilizador = Data.Result.ToString();
                    Class.ClassUtilizador classUser = JsonConvert.DeserializeObject<Class.ClassUtilizador>(Data.Result.ToString());

                //Call the function to update item
                adapter.Update(classUserOld.Result, classUser.Result);



                //Clean class and put the new data
                classUserOld = new Class.ClassUtilizador();
                classUserOld = classUser;

更新项目,删除,添加或移动项目。根据我的要求。

4

2 回答 2

2

您应该致电:

holder.bindingAdapterPosition
于 2021-01-28T07:40:35.500 回答
0

单击一个项目会将其返回给我一个与我单击的项目不匹配的位置

UserViewHolder.button.Click += (sender, args) =>
    {
          Toast.MakeText(context, ClassUser[position].Name, ToastLength.Short).Show();
        Console.WriteLine(ClassUser[position].Name);
    };

改成 :

UserViewHolder.button.Tag = position;
UserViewHolder.button.SetOnClickListener(this);

然后让你的适配器扩展View.IOnClickListener

class AdapterUser : RecyclerView.Adapter,View.IOnClickListener

public void OnClick(View v)
 {
   //here you could get the correct position
   Toast.MakeText(context, v.Tag.ToString(), ToastLength.Short).Show();
  }

如果它没有更新您的 Recyclerview,您可以在适配器中添加该方法:

public void setData(List<Class.Result> newList)
  {
    this.ClassUser= new List<Class.Result>(newList);
  }  

在你的update方法中:

public void Update(List<Class.Result> oldList, List<Class.Result> newList) 
{
    // Set detectMoves to true for smoother animations
    MyDiffCallback callback = new MyDiffCallback(oldList, newList);
    DiffUtil.DiffResult result = DiffUtil.CalculateDiff(callback);

    this.ClassUser.Clear();
    this.ClassUser.AddRange(newList);

    setData(this.ClassUser);
    // Despatch the updates to your RecyclerAdapter
    result.DispatchUpdatesTo(this);

}
于 2019-04-18T03:37:01.880 回答