在视图设置动画时调用setVisibility

时间:2016-11-30 14:31:54

标签: android animation view

当我使用ViewCompat.postOnAnimation对(父)视图进行动画制作时,我会在视图的子节点上调用setVisibility。 (setVisibility没有工作+其他一些东西被破坏了。)

问题 - 是否存在任何动画或变通方法,允许在父动画时调用setVisibility?

这是非常重要的请求,我认为不是那么不寻常,因为例如http请求是在随机时间内返回的,并且视图可以在此期间的任何时候进行动画处理。

代码请求编辑:

关于代码,它有点复杂。我先解释一下。它是自定义CoordinatorLayout Behavior中的动画,是标准BottomSheetBehavior的克隆(从下到上滑动工作表)。

通过调用此方式启动动画:

ViewCompat.postOnAnimation(child, new SettleRunnable(child, targetState));

SettleRunnable就是这样:

private class SettleRunnable implements Runnable {

    private final View mView;

    @State
    private final int mTargetState;

    SettleRunnable(View view, @State int targetState) {
        mView = view;
        mTargetState = targetState;
    }

    @Override
    public void run() {
        if (mViewDragHelper != null && mViewDragHelper.continueSettling(true)) {
            ViewCompat.postOnAnimation(mView, this);
        } else {
            setStateInternal(mTargetState);
        }
    }
}

如您所见,所有动画移动都是通过mViewDragHelper.continueSettling完成的。拖动助手是标准类ViewDragHelper。

ViewDragHelper.continueSettling看起来像这样

public boolean continueSettling(boolean deferCallbacks) {
    if (mDragState == STATE_SETTLING) {
        boolean keepGoing = mScroller.computeScrollOffset();
        final int x = mScroller.getCurrX();
        final int y = mScroller.getCurrY();
        final int dx = x - mCapturedView.getLeft();
        final int dy = y - mCapturedView.getTop();

        if (dx != 0) {
            ViewCompat.offsetLeftAndRight(mCapturedView, dx);
        }
        if (dy != 0) {
            ViewCompat.offsetTopAndBottom(mCapturedView, dy);
        }

        if (dx != 0 || dy != 0) {
            mCallback.onViewPositionChanged(mCapturedView, x, y, dx, dy);
        }

        if (keepGoing && x == mScroller.getFinalX() && y == mScroller.getFinalY()) {
            // Close enough. The interpolator/scroller might think we're still moving
            // but the user sure doesn't.
            mScroller.abortAnimation();
            keepGoing = false;
        }

        if (!keepGoing) {
            if (deferCallbacks) {
                mParentView.post(mSetIdleRunnable);
            } else {
                setDragState(STATE_IDLE);
            }
        }
    }

    return mDragState == STATE_SETTLING;
}

它根据所选目标状态简单地将工作表向上或向下设置为所需位置。

问题的伪代码是:

launchAnimation(); // it takes eg 300 ms
changeVisibilityOfAnimatedViewChildren(); // this is problem

我可以等到动画结束,但正如我所说,如果是http请求它有点问题,我想立即刷新数据而不用等待。

  • 动画元素是CoordinatorLayout。受setVisibility影响的孩子是其子女的一个或多个。

  • 根据this link判断,android似乎在动画和setVisibility方面存在问题。

我现在想到的可能的解决方案:

  • 也许我会用另一个并行的postOnAnimation()任务改变可见性(?)

  • 或者因为它基本上只是一步一步的后续调用移动函数mViewDragHelper.continueSettling()为什么不在没有postOnAnimation()的情况下执行它?没有它我也可以运行任务。但我想postOnAnimation为具体设备选择了一些正确的动画延迟步骤+可能还有其他一些东西。

1 个答案:

答案 0 :(得分:0)

您可以将AnimatorListenerAdapter添加到父动画中,并覆盖onAnimationEnd()方法。在此方法中,您可以调用子动画。但是,我宁愿更改视图的alpha而不是可见性。在这种情况下,您可以实现更流畅的效果。

例如,请考虑以下代码:

 parentAnimationInstance.addListener(new AnimatorListenerAdapter() {
                                            @Override
                                            public void onAnimationEnd(Animator animation) {
                                                super.onAnimationEnd(animation);
                                                childView.animate()
                                                    .alpha(1.f)
                                                    .setDuration(200)
                                                    .start();
                                            }
                                        });