user10943801
user10943801

Reputation:

Recyclerview not refreshing after removing an item

My Recycler view is not updating after an item is removed. This recyclerView is inside a fragment. I have tried every method and nothing works.

Adapter declaration in fragment class

    notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
                notificationItemsList, cListner);
        layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(notificationsTabAdapter);

RecyclerViewAdapter:

public class NotificationsTabAdapter extends RecyclerView.Adapter<NotificationsTabAdapter.NotificationItemHolder> {

Boolean debug = false;
public static final String NOTIFICATION_ADAPTER = "NotificationAdapter";
private ArrayList<NotificationItemm> notificationItems;
private int layoutResID;
private int notificationposition;
private Context myContext;
public onNotificationItemClickListner mListner;


public interface onNotificationItemClickListner {
    void onNotificationItemDelete(int position);
}

public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
                               onNotificationItemClickListner listner) {
    myContext = context;
    layoutResID = resource;
    notificationItems = notificationList;
    notificationposition = 0;
    this.mListner = listner;
}

@NonNull
@Override
public NotificationItemHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {

    View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.notifications_tab_item, viewGroup, false);
    NotificationsTabAdapter.NotificationItemHolder evh = new NotificationsTabAdapter.NotificationItemHolder(view, mListner);
    return evh;
}

@Override
public void onBindViewHolder(@NonNull final NotificationItemHolder notificationItemHolder, final int position) {

    final NotificationItemm currentItem = notificationItems.get(position);

    notificationItemHolder.mNotificationTextView.setText(currentItem.getNotification_name());
    notificationItemHolder.mNotificationURL = currentItem.getNotification_link();
    notificationItemHolder.mNotificationDate = currentItem.getNotification_date();
    notificationItemHolder.mNotificationRT = currentItem.getNotification_rT();

    notificationItemHolder.mNotificaionHolderLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    });
    //to delete the notification
    notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            deleteNotification(currentItem);

            mListner.onNotificationItemDelete(position);
        }
    });
}

@Override
public int getItemCount() {
    return notificationItems.size();
}

//Delete from View

public void deleteNotification(NotificationItemm todelete) {
    int notificationPosition = notificationItems.indexOf(todelete);
    notificationItems.remove(notificationPosition);
    notifyItemRemoved(notificationPosition);
    notifyItemChanged(notificationPosition);
    notifyDataSetChanged();
    notifyItemRemoved(notificationPosition);
    notifyItemChanged(notificationPosition);

    if (notificationItems.isEmpty()) {

    }
}

/**
 * VIEW HOLDER =================================================================================
 **/

public class NotificationItemHolder extends RecyclerView.ViewHolder {
    RelativeLayout mNotificaionHolderLayout;
    RelativeLayout notificationParentRelative;
    ImageView imageDelete;
    TextView mNotificationTextView;
    String mNotificationURL;
    String mNotificationDate;
    String mNotificationRT;

    public NotificationItemHolder(@NonNull View itemView, onNotificationItemClickListner listner) {

        super(itemView);
        mNotificationTextView = itemView.findViewById(R.id.NotificationTextView);
        mNotificaionHolderLayout = itemView.findViewById(R.id.notification__item_container);
        imageDelete = itemView.findViewById(R.id.notification_delete_image);
        notificationParentRelative = itemView.findViewById(R.id.rlNotificLayout);
        mNotificationRT = null;
        mNotificationURL = null;
        mNotificationDate = null;
    }
}

}

When I debug the project, I can see that the item is actually removing from the ArrayList.But not updating in recycled view.

After deletion, if the recyclerview is scrolled, the deleted item is removed from the recyclerview.But not without scrolling.

Upvotes: 3

Views: 1231

Answers (7)

jeevashankar
jeevashankar

Reputation: 1498

You have to parse the position which is getting from onclick listener in Adapter class to Interface method(onitemClicked()) Then, Implement the interface class to Fragment class and will remove the position which we have on Interface method using [ listname.remove(position)) ] Eventually, update recyclerview UI using adaptername.notifyDataSetChanged();

Step 1 :create interface class

public interface RecyclerviewItemClickListener {


    void onitemClicked(View v, int position);
}

Step 2: pass position to the interface method in adapter class

notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        deleteNotification(currentItem);
        //use interface method & pass the position of the list to fragment for update UI .
        recyclerviewItemClickListener.onitemClicked(v,position);
    }
});

step 3 : implement the interface class & method in fragment

@Override
    public void onitemClicked(View v, int position) {

        Listname.remove(Listname.get(position));
        RecyclerviewAdaptername.notifyDataSetChanged();
    }

Upvotes: 0

Basha K
Basha K

Reputation: 1519

In your NotificationsTabAdapter make the following changes

   NotificationsTabAdapterListener notificationsTabAdapterListener;

   public interface NotificationsTabAdapterListener { // create an interface
        void onItemsDeleted(int position); // create callback function
    }

public NotificationsTabAdapter(Context context, int resource, ArrayList<NotificationItemm> notificationList,
                           NotificationsTabAdapterListener notificationsTabAdapterListener) {
myContext = context;
layoutResID = resource;
notificationItems = notificationList;
notificationposition = 0;
this.notificationsTabAdapterListener = notificationsTabAdapterListener;

}

      notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
//perform normal remove operation here

notificationItems.remove(position);
            notificationsTabAdapterListener.onItemsDeleted(position);
        }
    });

And Implement NotificationsTabAdapterListener in you fragment and in override method use the following code

        @Override
public void onItemsDeleted(final int position) {
    notificationsTabAdapter.notifyDataSetChanged();
    recyclerView.post(new Runnable() {
        @Override
        public void run() {
            recyclerView.smoothScrollToPosition(position);

        }
    });
}

Upvotes: 0

prashant17
prashant17

Reputation: 1550

Try this:

    notificationItemHolder.imageDelete.setTag(holder);
    notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            NotificationItemHolder viewholder = (NotificationItemHolder) v.getTag();
            notificationItems.remove(viewholder.getAdapterPosition());
            notifyDataSetChanged();
        }
    });

Upvotes: 0

milad salimi
milad salimi

Reputation: 1660

Use a callback like this in your adapter :

private ICallback mICallback;

    public interface ICallback {

      void deleteItem(int position);
    }
    public SettingRecyclerViewAdapter(SettingMediator settingMediator, ICallback ICallback) {
        mICallback = ICallback;
        mSettingMediator = settingMediator;
    }

And in your faragment notifydatasetchange and update recyclerview like this :

public class YourFragment implements SettingContract.View, SettingRecyclerViewAdapter.ICallback {
.
.
.
    @Override
    public void deleteItem(int position) {

                //delete item from your list here
        mSettingRecyclerViewAdapter = new SettingRecyclerViewAdapter(yourList, this);
        mRecyclerView.setAdapter(mSettingRecyclerViewAdapter);
        mSettingRecyclerViewAdapter.notifyDataSetChanged();
    }


}

Upvotes: 0

Arti Patel
Arti Patel

Reputation: 681

Try this.Hope will work for you.

notificationItemHolder.imageDelete.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
           notificationItems.remove(position);
           notifyDataSetChanged();
    }

Upvotes: 1

Aiko West
Aiko West

Reputation: 791

As workaround you can call a method in the FragmentClass, which loads the new list (with item removed) in your adapter. Call this method from your Adapter

public void MethodInFragmentClass(NotificationItemm todelete)
{
/*
... delete item 
*/
notificationsTabAdapter = new NotificationsTabAdapter(getContext(), R.id.notificationsRecyclerView,
                notificationDeletedItemsList, cListner);

                recyclerView.setAdapter(notificationsTabAdapter);
}

Upvotes: 0

Akash Suresh Dandwate
Akash Suresh Dandwate

Reputation: 165

Try this to your delete functionality

public void deleteNotification(NotificationItemm todelete) {
    notificationItems.remove(todelete);
    notifyDataSetChanged();

}

Upvotes: 0

Related Questions