Android remove all recyclerview with animation on a button click

前端 未结 4 1776
無奈伤痛
無奈伤痛 2020-12-21 06:05

I have a recycler view. On a button click I want to remove all the items from the recyclerview but the items must be removed with animation. I am able to remove all the ite

相关标签:
4条回答
  • 2020-12-21 06:41

    It's old, but wish this helps someone else as it's already not answered yet; I have done it by deleting a single item at a time by simulating a swipe animation on this item, and post a delay before deleting the next item, and so on to the way down to the last item of the RecyclerView

    Step No.1:

    In your activity that holds the clear all button and the RecyclerView instance: Create a method of single item delete

    private void deleteItem(View rowView, final int position) {
    
        Animation anim = AnimationUtils.loadAnimation(requireContext(),
                android.R.anim.slide_out_right);
        anim.setDuration(300);
        rowView.startAnimation(anim);
    
        new Handler().postDelayed(new Runnable() {
            public void run() {
                if (myDataSource.size() == 0) {
                    addEmptyView(); // adding empty view instead of the RecyclerView
                    return;
                }
                myDataSource.remove(position); //Remove the current content from the array
                myRVAdapter.notifyDataSetChanged(); //Refresh list
            }
    
        }, anim.getDuration());
    }
    

    Step No.2:

    Create the method that will delete all RecyclerView list items >> call it in your button click callback.

    boolean mStopHandler = false;
    
    private void deleteAllItems() {
    
        final Handler handler = new Handler();
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
    
                if (myDataSource.size() == 0) {
                    mStopHandler = true;
                }
    
                if (!mStopHandler) {
                    View v = myRecyclerView.findViewHolderForAdapterPosition(0).itemView;
                    deleteItem(v, 0);
                } else {
                    handler.removeCallbacksAndMessages(null);
                }
    
                handler.postDelayed(this, 250);
            }
        };
        requireActivity().runOnUiThread(runnable);
    }
    

    Also it's important to handle configuration change in manifest, activity section, as if the configuration changes while clearing your recycler view list, an exception will be raised

    <activity
        android:name=".activities.MainActivity"
        android:configChanges="orientation|screenSize|keyboard"
        android:label="@string/app_name">
        ...
    </activity>
    

    0 讨论(0)
  • 2020-12-21 06:42

    This is how I have done without using any libraries - by inserting delays in the loop to remove items & restore (if needed)

    clearItemsView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                final List<LineItem> lineItemsCopy = new ArrayList<>(lineItems);
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        for (int i=0; i<lineItemsCopy.size(); i++) {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    salesOrderItemListAdapter.removeItem(0);
                                }
                            });
                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }).start();
                Snackbar snackbar = Snackbar.make(coordinatorLayout, getString(R.string.items_cleared_message), Snackbar.LENGTH_LONG)
                        .setAction(getString(R.string.label_undo), new View.OnClickListener() {
                            @Override
                            public void onClick(View v) {
                                new Thread(new Runnable() {
                                    @Override
                                    public void run() {
                                        for (int i=0; i<lineItemsCopy.size(); i++) {
                                            final int finalI = i;
                                            runOnUiThread(new Runnable() {
                                                @Override
                                                public void run() {
                                                    salesOrderItemListAdapter.restoreItem(lineItemsCopy.get(finalI), 0);
                                                }
                                            });
                                            try {
                                                Thread.sleep(500);
                                            } catch (InterruptedException e) {
                                                e.printStackTrace();
                                            }
                                        }
                                    }
                                }).start();
                            }
                        }).setActionTextColor(Color.YELLOW);
                snackbar.show();
            }
        });
    
    0 讨论(0)
  • 2020-12-21 06:45

    Extend BaseItemAnimator class of recyclerview-animators library:

    MyAdapter adapter = new MyAdapter(null);
    RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
    recyclerView.setAdapter(adapter);
    recyclerView.setItemAnimator(new MyScaleInLeftAnimator());
    
    findViewById(R.id.button).setOnClickListener(
        new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int count = adapter.getItemCount();
                adapter.clear();
                adapter.notifyItemRangeRemoved(0, count);
            }
        }
    );
    

    ...

    public class MyAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder{
        private ArrayList<String> mItems;
    
        ...
    
        public void clear() {
            if (mItems != null) {
                mItems.clear();
            }
        }
    
    }
    

    ...

    public class MyScaleInLeftAnimator extends BaseItemAnimator {
    
        private long lastRemoval;
        private int removeCount;
    
        public MyScaleInLeftAnimator() {
            lastRemoval = 0;
            removeCount = 0;
        }
    
        public MyScaleInLeftAnimator(Interpolator interpolator) {
            mInterpolator = interpolator;
            lastRemoval = 0;
            removeCount = 0;
        }
    
        @Override protected void preAnimateRemoveImpl(RecyclerView.ViewHolder holder) {
            ViewCompat.setPivotX(holder.itemView, 0);
        }
    
        @Override protected void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
            long time = System.currentTimeMillis();
            long d = time - lastRemoval;
            if (d < 100) {
                removeCount++;
            } else {
                removeCount = 0;
            }
            lastRemoval = time;
            ViewCompat.animate(holder.itemView)
                    .scaleX(0)
                    .scaleY(0)
                    .setDuration(getRemoveDuration())
                    .setInterpolator(mInterpolator)
                    .setListener(new DefaultRemoveVpaListener(holder))
                    .setStartDelay(removeCount * 100)
                    .start();
        }
    
        @Override protected void preAnimateAddImpl(RecyclerView.ViewHolder holder) {
            ViewCompat.setPivotX(holder.itemView, 0);
            ViewCompat.setScaleX(holder.itemView, 0);
            ViewCompat.setScaleY(holder.itemView, 0);
        }
    
        @Override protected void animateAddImpl(final RecyclerView.ViewHolder holder) {
            ViewCompat.animate(holder.itemView)
                    .scaleX(1)
                    .scaleY(1)
                    .setDuration(getAddDuration())
                    .setInterpolator(mInterpolator)
                    .setListener(new DefaultAddVpaListener(holder))
                    .setStartDelay(getAddDelay(holder))
                    .start();
        }
    }
    
    0 讨论(0)
  • 2020-12-21 06:51

    This is a pretty good library and what's better is the documentation for it. You can even insert durations for transitions and animations.

    Also, remember that if you are using default animation, after calling myDataSet.remove(pos) using adapter.notifyDataSetChanged() while there is an animation ongoing will cause the animation to stop.

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