【发布时间】:2017-04-14 22:19:20
【问题描述】:
当我在视图的子视图上调用 setVisibility 而(父)视图使用 ViewCompat.postOnAnimation 进行动画处理时,事情会被破坏。 (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 为具体设备选择了一些正确的动画步骤延迟 + 可能还有其他一些东西。
【问题讨论】:
-
可以分享代码吗?
-
嗨,我编辑了代码