实施"退回"使用ItemTouchHelper.Callback的RecyclerView动画

时间:2015-09-25 14:45:19

标签: android android-animation android-recyclerview

我正在尝试在RecyclerView行中创建一个动画,其中Helper类扩展为ItemTouchHelper.Callback

默认"滑动"使用ItemTouchHelper的行为是,如果以足够的速度滑动一行,它将从视图中消失(即,滑动到dimiss)。就我而言,我想创建一个动画,如果发生这样的事件,会导致行直接反弹。

我已经能够创建一个ValueAnimator,如果它在屏幕上滑动,会将该行设置为动画。但是,问题是我无法让父ItemTouchHelper类认识到它存储的x值已从行的宽度(因此它完全在屏幕外)更改为{{1 (以便它回到屏幕上)。

这意味着每当我在完成自定义动画后与该行进行交互时,即使该行完全可见,它的行为就好像该行仍在屏幕外。这通常意味着按下它意味着行从0的{​​{1}}位置跳到行宽的X位置,因此从屏幕再次激活回来边缘。在完全重置并再次正常运行之前,它会执行此操作几次。

此视频有助于显示问题。由于前两次滑动不在屏幕外,因此默认行为有效。然后将行从屏幕上滑下并反弹回来,点击该行显示它从右边缘向后ping:

Youtube - Issue with ItemTouchHelper.Callback

以下是我用来进行动画的代码:

0

请注意,此内部类X是从public class CustomItemTouchHelper extends ItemTouchHelper.Callback { private RecoverAnimation ra; private boolean animatorRunning; //... @Override public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) { final float per = (dX/viewHolder.itemView.getWidth()); if (per > 0.8F && !animatorRunning && !isCurrentlyActive) { ra = new RecoverAnimation(c, recyclerView, viewHolder, ItemTouchHelper.ANIMATION_TYPE_SWIPE_CANCEL, actionState, dX, dY, 0, 0); ra.start(); } else { getDefaultUIUtil().onDraw(c, recyclerView, viewHolder.itemView, dX, dY, actionState, isCurrentlyActive); } } //... 源代码中提取的:

RecoverAnimation

我有什么办法可以解决这个问题,或者它是否根本不可能?(

1 个答案:

答案 0 :(得分:6)

以下解决方案将在不实施自定义RecoverAnimation类的情况下退回recyclelerview项目。

    public class CustomItemTouchHelper extends ItemTouchHelper.Callback {

        private RecoverAnimation ra;
        private boolean animatorRunning;
        private boolean swipeBack = false;

    //...

        @Override
        public void onChildDraw(Canvas c, RecyclerView recyclerView, RecyclerView.ViewHolder viewHolder, float dX, float dY, int actionState, boolean isCurrentlyActive) {
            recyclerView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event)
            {
                if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL)
                {
                    swipeBack = true;
                }
                else
                {
                    swipeBack = false;
                }
                return false;
            }
        });
        }

        @Override
        public int convertToAbsoluteDirection(int flags, int layoutDirection) {
             return swipeBack ? 0 : super.convertToAbsoluteDirection(flags, layoutDirection);
        }

    //...