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); 

为什么我第一次打开面板没有动画,但所有其他的人存在?

+0

您确定它不起作用吗?尝试调试它的一些日志。当你的面板不可见或者正在创建视图时,Mabye会启动吗? – ania

+0

它不起作用。只有在第一次打开后,动画才能用于打开和关闭 – piojo

+0

我发现了一种解决方案:不是将面板的可见性设置为“GONE”,而是在应用程序启动时关闭面板 – piojo

你打电话给这个?它可能只是在“第一次之后”这样做,因为面板在第一次调用时尚未渲染,并且getHeight()正在返回0.请尝试等待,直到getHeight()有值,然后开始动画。你也可以尝试对价值进行硬编码,以测试我的理论是否正确。

+0

您正确。我尝试了'getMeasuredHeight()',我认为它会在渲染之前提供高度,但显然它不是。有没有比我在上面评论中写的更好的解决方案? – piojo

+0

我不知道你的上下文(大概这是一个小部件?),如果你正在做一个自定义的视图,你可以看看[这个问题](http://stackoverflow.com/questions/2864331/how-to -get-an-android-widgets-size-after-layout-is-calculated)建议的替代方案。 – dmon

+0

对此问题的此答案对我的方案无效。当应用程序启动并运行时调用'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

+0

如果您还需要移动当前可见的视图,则需要在'onCreate()'中计算高度。看看[这个答案](http://stackoverflow.com/a/10134260/1902059)如何。 – willlma