【问题标题】:Android remove all recyclerview with animation on a button clickAndroid通过单击按钮删除所有带有动画的recyclerview
【发布时间】:2017-11-30 10:46:37
【问题描述】:

我有一个回收者的观点。单击按钮时,我想从 recyclerview 中删除所有项目,但必须使用动画删除这些项目。 我可以一次删除所有项目,但我不知道如何用动画删除它们。谢谢

【问题讨论】:

标签: android animation android-recyclerview android-animation


【解决方案1】:

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

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

【讨论】:

  • 我想一次删除所有元素。我不知道如何实现。
  • 它们会根据您循环的方式按特定顺序执行,因此请尝试计数器:依次执行每个项目myDataSet.remove(pos)adapter.notifyDataSetChanged()。或者您可以尝试使用命令recyclerView.getItemAnimator().setRemoveDuration(1); 提到的相同库
【解决方案2】:

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

【讨论】:

  • 谢谢,视图随着动画的消失而消失。我可以在相同的代码中制作滑出动画吗
  • 您可以扩展 SimpleItemAnimator 类并实现您需要的动画。此处示例:link
  • 您也可以使用@MRX 建议和recyclerview-animators 库。它很容易使用:将 compile 'jp.wasabeef:recyclerview-animators:2.2.6' 添加到您的应用 build.gradle 并调用 recyclerView.setItemAnimator(new SlideInLeftAnimator());
  • 我已经尝试过该库,也称为 rView.setItemAnimator(new SlideInLeftAnimator());但问题是,我所有的元素都只能一次向左滑动,我想要的是一次一个项目将向左移动。就像一个视图向左滑动,然后第二个和逐渐最后一个可见的项目向左滑出
  • 扩展 recyclerview-animators 库的 BaseItemAnimator 类(参见上面的 MyScaleInLeftAnimator 类)。
【解决方案3】:

这就是我在不使用任何库的情况下所做的 - 通过在循环中插入延迟来删除项目并恢复(如果需要)

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

【讨论】:

    【解决方案4】:

    它很旧,但希望这对其他人有帮助,因为它还没有得到回答;我通过在该项目上模拟滑动动画来一次删除一个项目,并在删除下一个项目之前发布延迟,依此类推到RecyclerView的最后一个项目。

    第一步:

    在您的包含全部清除按钮和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());
    }
    

    第 2 步:

    创建将删除所有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>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-19
      • 2020-08-01
      • 2016-09-15
      • 1970-01-01
      • 2020-11-02
      • 1970-01-01
      相关资源
      最近更新 更多