Android - 动画视图并改变他的真实位置(另一个视图跟随行为依赖)
Android - Animate a view and change his real position (and another view follow with behavior dependency)
我正在尝试使用 ViewDragHelper 为我的 appBar 设置动画,当我向下拖动它时,它应该会启动动画并向下移动。
在顶部我有另一个视图(the example 中的粉红色)"follow" 我的应用栏有一个行为(顶部视图取决于 AppBarLayout)。
As you can see here 应用栏是动画的,但 "real" 位置没有改变,显然,我的顶部框架没有移动。
为了制作动画,我使用了以下代码:
@Override
public void onViewReleased(final View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild.getTop() > childHeight) {
Log.e("TAG", "SHOULD SCROLL " + releasedChild.getTop() + " > " + childHeight);
final int offset = height - releasedChild.getTop() - 100;
ViewCompat.animate(releasedChild).translationY(offset).setDuration(1000).setInterpolator(new OvershootInterpolator()).start();
} else {
Log.e("TAG", "SHOULD NOT SCROLL " + releasedChild.getTop() + " < " + childHeight);
eleasedChild.offsetTopAndBottom(-releasedChild.getTop());
}
if (mDragFrameLayoutController != null) {
mDragFrameLayoutController.onDragDrop(false);
}
}
我尝试过许多其他动画:
TranslateAnimation scale = new TranslateAnimation(0.0f, 0.0f, 0.f, offset);
scale.setInterpolator(new OvershootInterpolator());
scale.setDuration(3000L);
scale.setFillEnabled(true);
scale.setFillAfter(true);
scale.setAnimationListener(new Animation.AnimationListener() {
或
ObjectAnimator moveY = ObjectAnimator.ofInt(releasedChild, "y", releasedChild.getTop(), offset);
AnimatorSet as = new AnimatorSet();
as.play(moveY);
as.start();
所有这些片段都给我相同的结果。
我发现移动视图的唯一方法是使用偏移,但这没有动画效果,它只是向下移动...
releasedChild.offsetTopAndBottom(offset);
有什么想法吗?谢谢。
我终于找到了解决方案:
在我的 viewDragHelper 上,我覆盖了以下方法:
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if(yvel>0) {
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getMeasuredHeight()-releasedChild.getMeasuredHeight());
} else {
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);
}
invalidate();
}
然后在我的自定义视图中覆盖了以下方法:
@Override
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
一切正常!
我希望这可以帮助将来的人。
我正在尝试使用 ViewDragHelper 为我的 appBar 设置动画,当我向下拖动它时,它应该会启动动画并向下移动。
在顶部我有另一个视图(the example 中的粉红色)"follow" 我的应用栏有一个行为(顶部视图取决于 AppBarLayout)。
As you can see here 应用栏是动画的,但 "real" 位置没有改变,显然,我的顶部框架没有移动。
为了制作动画,我使用了以下代码:
@Override
public void onViewReleased(final View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if (releasedChild.getTop() > childHeight) {
Log.e("TAG", "SHOULD SCROLL " + releasedChild.getTop() + " > " + childHeight);
final int offset = height - releasedChild.getTop() - 100;
ViewCompat.animate(releasedChild).translationY(offset).setDuration(1000).setInterpolator(new OvershootInterpolator()).start();
} else {
Log.e("TAG", "SHOULD NOT SCROLL " + releasedChild.getTop() + " < " + childHeight);
eleasedChild.offsetTopAndBottom(-releasedChild.getTop());
}
if (mDragFrameLayoutController != null) {
mDragFrameLayoutController.onDragDrop(false);
}
}
我尝试过许多其他动画:
TranslateAnimation scale = new TranslateAnimation(0.0f, 0.0f, 0.f, offset);
scale.setInterpolator(new OvershootInterpolator());
scale.setDuration(3000L);
scale.setFillEnabled(true);
scale.setFillAfter(true);
scale.setAnimationListener(new Animation.AnimationListener() {
或
ObjectAnimator moveY = ObjectAnimator.ofInt(releasedChild, "y", releasedChild.getTop(), offset);
AnimatorSet as = new AnimatorSet();
as.play(moveY);
as.start();
所有这些片段都给我相同的结果。
我发现移动视图的唯一方法是使用偏移,但这没有动画效果,它只是向下移动...
releasedChild.offsetTopAndBottom(offset);
有什么想法吗?谢谢。
我终于找到了解决方案:
在我的 viewDragHelper 上,我覆盖了以下方法:
@Override
public int getViewVerticalDragRange(View child) {
return getMeasuredHeight() - child.getMeasuredHeight();
}
@Override
public void onViewReleased(View releasedChild, float xvel, float yvel) {
super.onViewReleased(releasedChild, xvel, yvel);
if(yvel>0) {
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), getMeasuredHeight()-releasedChild.getMeasuredHeight());
} else {
mDragHelper.settleCapturedViewAt(releasedChild.getLeft(), 0);
}
invalidate();
}
然后在我的自定义视图中覆盖了以下方法:
@Override
public void computeScroll() {
super.computeScroll();
if (mDragHelper.continueSettling(true)) {
ViewCompat.postInvalidateOnAnimation(this);
}
}
一切正常! 我希望这可以帮助将来的人。