我使用了一些我在滑动面板上找到的代码,基本上它可以工作,但问题很小。
动画在第一次打开面板时不起作用。
这是动画的代码:
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);
为什么第一次打开面板时没有动画,但其他所有动画都有?
答案 0 :(得分:6)
getHeight()
正在返回0.尝试等待getHeight()
有一个值并启动动画然后。您也可以尝试将值硬编码为某种东西,以测试我的理论是否正确。
答案 1 :(得分:0)
我使代码工作的方式:
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);
}
这就是它的本质。希望它有所帮助。
答案 2 :(得分:0)
如果您只是想要制作动画的一个视图,那么您可以像这样用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
。
答案 3 :(得分:0)
你可以使用延迟来工作
TranslateAnimation animate1 = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
0, // fromYDelta
binding.saveCardview.getMeasuredHeight()); // toYDelta
animate1.setDuration(500);
animate1.setFillAfter(true);
binding.saveCardview.startAnimation(animate1);
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
//Do something after 100ms
binding.saveCardview.setVisibility(View.GONE);
TranslateAnimation animate2 = new TranslateAnimation(
0, // fromXDelta
0, // toXDelta
binding.carCardview.getHeight(), // fromYDelta
0); // toYDelta
animate2.setDuration(1000);
animate2.setFillAfter(true);
binding.carCardview.startAnimation(animate2);
}
}, 500);