Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

notifyItemChanged not refreshing view

First of all, I worked on this all day but could not get anything done. I have a RecyclerView with an adapter that uses RecyclerView's SortedList. I tried implementing TouchHelper with the callback class:

public class TimerListTouchHelperCallback extends ItemTouchHelper.SimpleCallback {

    private OnItemChangeListener onItemChangeListener;

    public TimerListTouchHelperCallback(OnItemChangeListener listener, int dragDirs, int swipeDirs) {
        super(dragDirs, swipeDirs);

        this.onItemChangeListener = listener;

    }

    @Override
    public int getSwipeDirs(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder) {
        TimerHolder holder = (TimerHolder) viewHolder;

        int holderState = holder.getState();

        if (holderState == TimerHolder.TIMER_PENDING_DELETE) return 0;
        else return super.getSwipeDirs(recyclerView, viewHolder);
    }

    @Override
    public boolean onMove(RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, RecyclerView.ViewHolder target) {
        return false;
    }




    @Override
    public void onSwiped(RecyclerView.ViewHolder viewHolder, int swipeDir) {
        TimerHolder holder = (TimerHolder) viewHolder;

        int position = holder.getAdapterPosition();
        // ViewHolder's state is changed that should handle the layout change.
        holder.setState(TimerHolder.TIMER_PENDING_DELETE); 

        if (onItemChangeListener != null) onItemChangeListener.onItemSwiped(position);
    }


    protected interface OnItemChangeListener{
        void onItemSwiped(int position);
    }
}

Here is the initialization of the TouchHelper

timerAdapter = new TimerAdapter(this, timerList);
    timerListView.setAdapter(timerAdapter);

TimerListTouchHelperCallback touchHelperCallback = new TimerListTouchHelperCallback(
        timerAdapter,
        ItemTouchHelper.LEFT,
        ItemTouchHelper.LEFT);

ItemTouchHelper swipeToDismissTouchHelper = new ItemTouchHelper(touchHelperCallback);

swipeToDismissTouchHelper.attachToRecyclerView(timerListView);

My adapter implements the interface OnItemChangeListener

@Override
public void onItemSwiped(int position) {
    notifyItemChanged(position);
    removalPendingTimers.add(timerList.get(position));
}

My ViewHolder reads the state and when the state is TimerHolder.TIMER_PENDING_DELETE it hides the rest of the view and shows the interface with an undo button. But this is not happening until I scroll the view out and scroll it back again. Any suggestions what I am missing?

Problem case

Links

Adapter class ViewHolder class

like image 302
Aayush Subedi Avatar asked Aug 18 '16 14:08

Aayush Subedi


2 Answers

Finally got it running. Since notifyItemChanged was not cutting it (which it should have), I used notifyItemRemoved followed by notifyItemInserted.

Lags just a little bit but works.

like image 138
Aayush Subedi Avatar answered Oct 04 '22 01:10

Aayush Subedi


I've created a simple example Android App to better understand the question.

It makes use of notifyItemChanged(position); when the user swipes the item left or right to show the undo view. When the undo time expires it calls notifyItemRemoved(position) to remove it from the list. See the GIF for example, does not leave any empty rows.

https://github.com/DawidvanGraan/ExampleRecycleViewSwipeDismiss

like image 25
Dawid van Graan Avatar answered Oct 04 '22 00:10

Dawid van Graan