TranslateAnimation - 动画仅在第二次后才起作用
我使用了一些我找到的用于滑动面板的代码,基本上它可以工作,但有一个小问题。TranslateAnimation - 动画仅在第二次后才起作用
动画在面板第一次打开时不起作用。
这里是动画的代码:
TranslateAnimation anim = null;
m_isOpen = !m_isOpen;
if (m_isOpen) {
setVisibility(View.VISIBLE);
anim = new TranslateAnimation(0.0f, 0.0f, getHeight(), 0.0f);
} else {
anim = new TranslateAnimation(0.0f, 0.0f, 0.0f, getHeight());
anim.setAnimationListener(new Animation.AnimationListener() {
public void onAnimationEnd(Animation animation) {
setVisibility(View.GONE);
}
public void onAnimationRepeat(Animation animation) {
// not needed
}
public void onAnimationStart(Animation animation) {
// not needed
}
});
}
anim.setDuration(300);
anim.setInterpolator(new AccelerateInterpolator(1.0f));
startAnimation(anim);
为什么我第一次打开面板没有动画,但所有其他的人存在?
你打电话给这个?它可能只是在“第一次之后”这样做,因为面板在第一次调用时尚未渲染,并且getHeight()
正在返回0.请尝试等待,直到getHeight()
有值,然后开始动画。你也可以尝试对价值进行硬编码,以测试我的理论是否正确。
您正确。我尝试了'getMeasuredHeight()',我认为它会在渲染之前提供高度,但显然它不是。有没有比我在上面评论中写的更好的解决方案? – piojo
我不知道你的上下文(大概这是一个小部件?),如果你正在做一个自定义的视图,你可以看看[这个问题](http://stackoverflow.com/questions/2864331/how-to -get-an-android-widgets-size-after-layout-is-calculated)建议的替代方案。 – dmon
对此问题的此答案对我的方案无效。当应用程序启动并运行时调用'getHeight()'。 – piojo
我做的,代码工作的方式:
final ViewGroup viewGroup = (ViewGroup) findViewById(R.id.panel);
viewGroup.setVisibility(View.VISIBLE);
final ViewTreeObserver treeObserver = viewGroup.getViewTreeObserver();
if (treeObserver.isAlive()) {
final OnPreDrawListener l = new OnPreDrawListener() {
@Override
public boolean onPreDraw() {
treeObserver.removeOnPreDrawListener(this);
TranslateAnimation anim = new TranslateAnimation(0.0f, 0.0f, viewGroup.getHeight(), 0.0f);
anim.setDuration(1000);
anim.setInterpolator(new AccelerateInterpolator(1.0f));
viewGroup.startAnimation(anim);
return false;
}
};
treeObserver.addOnPreDrawListener(l);
}
这就是它的精华所在。希望能帮助到你。
如果只有一个,就是你想要进行动画视图,那么您可以编写动画XML像这样:
<translate
xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/accelerate_interpolator"
android:fromYDelta="-100%"
(or)
android:toYDelta="-100%"
android:duration="300"/>
这样,你不需要使用getHeight()
。那么Java部分看起来是这样的:
final View flashTitle = findViewById(R.id.flash_title);
Animation slideDownOnscreen = AnimationUtils.loadAnimation
(this, R.anim.slide_down_onscreen);
flashTitle.setAnimation(slideDownOnscreen);
flashTitle.setVisibility(View.VISIBLE);
另外,如果你需要结合动画若干意见,做了以上所述与第一视图和动画在post runnable
所以后续的观点,即getHeight()
返回正确的高度第一种观点,像这样的:
flashTitle.post(new Runnable() {
@Override
public void run() {
System.out.println("NOTE flashTitle height: "+flashTitle.getHeight());
Animation slideDown = new TranslateAnimation(0, 0,
-flashTitle.getHeight(),0);
slideDown.setDuration(300);
flashLine.setVisibility(View.VISIBLE);
flashLine.startAnimation(slideDown);
//(or)flashLine.animate().translationYBy(flashTitle.getHeight()).setDuration(300);
}
});
您还需要添加accelerate_interpolator
作为Android的默认值是accelerate_decelerate_interpolator
。
如果您还需要移动当前可见的视图,则需要在'onCreate()'中计算高度。看看[这个答案](http://stackoverflow.com/a/10134260/1902059)如何。 – willlma
您确定它不起作用吗?尝试调试它的一些日志。当你的面板不可见或者正在创建视图时,Mabye会启动吗? – ania
它不起作用。只有在第一次打开后,动画才能用于打开和关闭 – piojo
我发现了一种解决方案:不是将面板的可见性设置为“GONE”,而是在应用程序启动时关闭面板 – piojo