Почему мои diffutils не обновляют мою позицию в фоновом режиме - PullRequest
0 голосов
/ 17 апреля 2019

Я использую 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);

    }

Мои DiffUtills:

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;

Обновление элементов, удаление, добавление или перемещение элементов.В зависимости от моего запроса.

1 Ответ

0 голосов
/ 18 апреля 2019

нажатие на элемент возвращает мне позицию, которая не соответствует элементу, на котором я щелкнул

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

}
...