Android会在单击按钮时删除所有带有动画的recyclelerview

时间:2017-06-27 11:35:34

标签: android animation android-recyclerview android-animation

我有一个回收者视图。在按钮上单击我想从recyclerview中删除所有项目,但必须使用动画删除项目。 我可以一次删除所有项目,但我不知道如何用动画删除它们。感谢

4 个答案:

答案 0 :(得分:1)

它已经很旧了,但希望它对其他人有所帮助,因为它尚未得到答复;我通过模拟一个项目的一次滑动动画来一次删除一个项目,并在删除下一个项目之前发布了一个延迟,依此类推直到RecyclerView <的最后一个项目。 / p>

第1步:

在拥有“清除所有”按钮和RecyclerView实例的活动中:创建一种删除单个项目的方法

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

第二步:

创建一种方法,该方法将删除所有RecyclerView列表项>>在按钮单击回调中调用它。

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

同样重要的是,在清单,活动部分中处理配置更改,就好像在清除回收者视图列表时配置更改一样,也会引发异常

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

答案 1 :(得分:0)

This是一个非常好的库,它的文档更好。您甚至可以插入过渡和动画的持续时间。

另外,请记住,如果您使用默认动画,则在动画正在进行时使用myDataSet.remove(pos)调用adapter.notifyDataSetChanged()将导致动画停止。

答案 2 :(得分:0)

扩展recyclerview-animators库的BaseItemAnimator类:

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

答案 3 :(得分:0)

这就是我没有使用任何库的方法 - 在循环中插入延迟以删除项目&amp;恢复(如果需要)

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