我有一个RelativeLayout
,它显示一些控件,我想使用上下滑动动画来隐藏和显示它们。
这对于第一次向下滑动和下一次向上滑动来说都很好,但在那之后,它就无缘无故地停止了工作。
以下是执行动画的代码:
final ViewGroup controlsLayout = (ViewGroup) findViewById(R.id.controlsLayout);
final boolean show = controlsLayout.getTag() instanceof Boolean && controlsLayout.getTag().equals(Boolean.FALSE);
Animation anim;
if( show ) {
anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_up);
controlsLayout.setTag(Boolean.TRUE);
}
else{
anim = AnimationUtils.loadAnimation(getApplicationContext(), R.anim.slide_down);
controlsLayout.setTag(Boolean.FALSE);
}
anim.setAnimationListener(new Animation.AnimationListener() {
@Override public void onAnimationStart(Animation animation) {}
@Override public void onAnimationRepeat(Animation animation) {}
@Override
public void onAnimationEnd(Animation animation) {
// If we slided down, then hide the controls after the slide is done
if( !show )
controlsLayout.setVisibility(View.GONE);
}
});
// Before starting the animation, we make sure the view is visible
controlsLayout.setVisibility(View.VISIBLE);
controlsLayout.startAnimation(anim);
变量show
的值在每次运行时按预期进行切换。第一次运行代码时,控件会向下滑动。下次他们滑上来的时候。但下一次(即使节目被切换),动画甚至还没有开始。。。
slide_down.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="1000"
android:fromYDelta="0"
android:toYDelta="100%" />
</set>
slide_up.xml
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
<translate
android:duration="1000"
android:fromYDelta="100%"
android:toYDelta="0" />
</set>
我认为问题是,当您将布局设置为controlsLayout.setVisibility(View.GONE);
时,android不会在下一次运行时渲染您的布局,而您正试图在尚未渲染的视图上设置动画,动画将在没有布局的视图上发生。动画完成后,它将对其进行渲染,然后突然出现没有动画的视图。
所以我建议你保持可见性为INVISIBLE而不是GONE,如果你不能做到这一点,那么你应该先让它不可见,然后应用动画,然后在动画之后让它可见。
另一种方法可以是在xml
中简单地使用android:animateLayoutChanges="true"
进行默认动画,并且效果非常好。
希望它能帮助
好吧,这太愚蠢了。现在,我在问题中发布的代码完全相同。问题似乎出在Android Studio 2.0中的"即时运行"功能上。出于某种原因,当代码使用"即时运行"上传"到我的手机时,它不起作用,但当我重新启动并重建应用程序时,它起作用了。
无论如何,这是我在尝试使用ObjectAnimator
找到有效解决方案时发现的一个替代解决方案。
final ViewGroup controlsLayout = (ViewGroup) findViewById(R.id.controlsLayout);
ObjectAnimator.ofFloat(
controlsLayout,
"translationY",
controlsLayout.getTranslationY(),
(controlsLayout.getTranslationY() > 0) ? 0 : controlsLayout.getHeight()
).start();