RecyclerView ItemTouchHelper刷卡删除动画 [英] RecyclerView ItemTouchHelper swipe remove animation

查看:821
本文介绍了RecyclerView ItemTouchHelper刷卡删除动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个去除轻扫,绘制背景(很像收件箱中的应用程序),由ItemTouchHelper实现 - 通过重写onChilDraw方法和所提供的画布上绘制一个矩形:

I've got a remove on swipe, that draws a background (much like the Inbox app), implemented by an ItemTouchHelper - by overriding the onChilDraw method and drawing a rectangle on the provided canvas:

    ItemTouchHelper mIth = new ItemTouchHelper(
        new ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {

            public void onSwiped(RecyclerView.ViewHolder viewHolder, int direction) {
                remove(viewHolder.getAdapterPosition());
            }

            public boolean onMove(RecyclerView recyclerview, RecyclerView.ViewHolder v, RecyclerView.ViewHolder target) {
                return false;
            }

            @Override
            public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {

                View itemView = viewHolder.itemView;

                Drawable d = ContextCompat.getDrawable(context, R.drawable.bg_swipe_item_right);
                d.setBounds(itemView.getLeft(), itemView.getTop(), (int) dX, itemView.getBottom());
                d.draw(c);

                super.onChildDraw(c, recyclerView, viewHolder, dX, dY, actionState, isCurrentlyActive);
            }
        });

以上所谓的删除方法是在适配器:

The remove method called above is in the Adapter:

    public void remove(int position) {
       items.remove(position);
       notifyItemRemoved(position);
    }

背景引出很好,但是当notifyItemRemoved是(根据调试先生)调用,RecyclerView首先删除我的pretty的绿色背景,然后推动两个相邻的物品放在一起。

The background draws out nicely, but when notifyItemRemoved is called (according to Mr. Debugger), the RecyclerView first deletes my pretty green background, and then pushes the two adjacent items together.

我想它保持背景那里,而它的(就像收件箱中的应用程序)。有没有办法做到这一点?

I would like it to keep the background there while it does that (just like the Inbox app). Is there any way to do that?

推荐答案

我设法得到它通过的 Wasabeefs的recyclerview-动画库。

I managed to get it to work by using Wasabeefs's recyclerview-animators library.

我ViewHolder现在扩展了图书馆的规定AnimateViewHolder:

My ViewHolder now extends the library's provided AnimateViewHolder:

    class MyViewHolder extends AnimateViewHolder {

    TextView textView;

    public MyViewHolder(View itemView) {
        super(itemView);
        this.textView = (TextView) itemView.findViewById(R.id.item_name);
    }

    @Override
    public void animateAddImpl(ViewPropertyAnimatorListener listener) {
        ViewCompat.animate(itemView)
                .translationY(0)
                .alpha(1)
                .setDuration(300)
                .setListener(listener)
                .start();
    }

    @Override
    public void preAnimateAddImpl() {
        ViewCompat.setTranslationY(itemView, -itemView.getHeight() * 0.3f);
        ViewCompat.setAlpha(itemView, 0);
    }

    @Override
    public void animateRemoveImpl(ViewPropertyAnimatorListener listener) {
        ViewCompat.animate(itemView)
                .translationY(0)
                .alpha(1)
                .setDuration(300)
                .setListener(listener)
                .start();
    }

}

在overrided功能的实现是相同的是什么recyclerview,动画师在GitHub上的自述。

The overrided function implementations are identical to what is in recyclerview-animators' readme on github.

这也似乎有必要的ItemAnimator更改为一个自定义,并设置removeDuration为0(或其他低价值 - 这是prevent一些闪烁):

It also seems necessary to change the ItemAnimator to a custom one and set the removeDuration to 0 (or another low value - this is to prevent some flickering):

    recyclerView.setItemAnimator(new SlideInLeftAnimator());
    recyclerView.getItemAnimator().setRemoveDuration(0);

这不会引起任何问题,因为正常(非刷卡)除去中使用的动画是一个在AnimateViewHolder

This doesn't cause any problems as the normal (non-swiping) remove animation used is the one in the AnimateViewHolder.

其他所有code保持了相同的问题。我还没有弄清楚这个内部的工作还没有的时候,但如果有人感觉就像做随时更新这个答案。

All other code was kept the same as in the question. I haven't had the time to figure out the inner workings of this yet, but if anyone feels like doing it feel free to update this answer.

更新:设置 recyclerView.getItemAnimator()setRemoveDuration(0)实际上打破了刷卡的重新绑定的动画。幸运的是,删除该行并设置在animateRemoveImpl持续时间较长(500对我的作品)也解决了闪烁问题。

Update: Setting recyclerView.getItemAnimator().setRemoveDuration(0); actually breaks the "rebind" animation of the swipe. Fortunately, removing that line and setting a longer duration in animateRemoveImpl (500 works for me) also solves the flickering problem.

更新2:原来,ItemTouchHelper.SimpleCallback使用ItemAnimator动画的持续时间,这也是为什么上述setRemoveDuration(0)打破了刷卡动画。简单地重写它的方法getAnimationDuration为:

Update 2: Turns out that ItemTouchHelper.SimpleCallback uses ItemAnimator's animation durations, which is why the above setRemoveDuration(0) breaks the swipe animation. Simply overriding it's method getAnimationDuration to:

@Override
public long getAnimationDuration(RecyclerView recyclerView, int animationType, float animateDx, float animateDy) {
    return animationType == ItemTouchHelper.ANIMATION_TYPE_DRAG ? DEFAULT_DRAG_ANIMATION_DURATION
            : DEFAULT_SWIPE_ANIMATION_DURATION;
}

解决了这个问题。

solves that problem.

这篇关于RecyclerView ItemTouchHelper刷卡删除动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆