How stick to with Adapter position while it's scrolling in Android?

前端 未结 2 471
日久生厌
日久生厌 2020-12-22 07:20

The problem is, in my recyclerview - adapter, clicking on delete button, I\'m showing small progressbar in place of delete button. Now suppose it is taking 2 minutes to comp

相关标签:
2条回答
  • 2020-12-22 08:10
    1. create variable inside Events object
    public class Events {
        // your parametters bla bla
    
        boolean isDeleting = false;
    
        public boolean isDeleting() {
            return isDeleting;
        }
    
        public void setDeleting(boolean deleting) {
            isDeleting = deleting;
        }
    }
    
    1. Change your view holder to this
    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        Events events = eventList.get(position);
    
        holder.progressBar.setVisibility(events.isDeleting() ? View.VISIBLE : VIEW.GONE)
        holder.delete.setVisibility(events.isDeleting() ? View.GONE : View.VISIBLE);
        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) {
                    holder.delete.setVisibility(View.GONE);
                    holder.progressBar.setVisibility(View.VISIBLE);
                    eventList.get(position).setDeleting(true)
                    listener.onClicked(position, eventList.get(position).getEventId());
                }
            }
        });
    
    0 讨论(0)
  • 2020-12-22 08:16

    I think this is a very usual problem of updating views dynamically on a RecyclerView. A simple fix could be saving the position of the item that is currently being deleted and set the progress spinner in your onBindViewHolder based on the positions that you stored.

    Let us take an extra variable in the Event class as pointed in the other answer here. This is to keep track of the item deletion.

    public class Event {
        // ... Your other variables will go here
        public boolean isDeleting = false; // Set the default value to false 
    }
    

    Now in the onClickListener of delete button, update the status of the variable to indicate if the item is being deleted.

    @Override
    public void onBindViewHolder(final MyViewHolder holder, final int position) {
        Events events = eventList.get(position);
    
        holder.delete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (listener != null) {
                   // We do not need setting the visibility here. The next actions for notifyDataSetChanged will take care of this. 
                   // holder.delete.setVisibility(View.GONE);
                   // holder.progressBar.setVisibility(View.VISIBLE);
                   eventList.get(position).isSelected = true;
                   eventList.get(position).isDeleting = true; // Set the variable to true to indicate that the item is being deleted
                   listener.onClicked(position, eventList.get(position).getEventId());
    
                   // It is important here to notify the list that the views are changed when the delete button is clicked. Hence call the notifyDataSetChanged
                   notifyDataSetChanged();
                }
            }
        });
    
        // Now let us update the views based on the selection for deletion
        if (eventList.get(position).isDeleting) {
             // The item is being deleted 
             holder.progressBar.setVisibility(View.VISIBLE);
             holder.delete.setVisibility(View.GONE);
        } else {
            // The item is not being deleted (normal case) 
             holder.progressBar.setVisibility(View.GONE);
             holder.delete.setVisibility(View.VISIBLE);            
        }
    }
    

    Now from the updateView function, you need to set up the eventList as required and call the notifyDataSetChanged again to get the updated views in your RecyclerView.

    public void updateView(int position) {
        // Update the eventList 
        eventList.remove(position); // Remove the item that was deleted by the index
        // Now let the RecyclerView know that the list is updated as one of the items is removed. 
        notifyDataSetChanged();
    }
    

    You should be good to go!

    Update

    I could not run the program that you shared. However, I had a chance to look into the activity and the adapter class. It looks like there are some other problems here.

    The eventList is an ArrayList which is not a thread-safe data-structure. You are trying to remove an event in a background thread and updating the RecyclerView when the deletion is complete on that thread. Hence, when you are trying to delete multiple items at the same time, you cannot really ensure that the list will be updated accordingly.

    You might consider having a synchronized deletion or using a thread-safe data structure to avoid this concurrent-modification problem in your eventList.

    0 讨论(0)
提交回复
热议问题