2011-11-21 4 views
1

슬라이딩 패널에서 찾은 코드를 사용했지만 기본적으로 작동하지만 작은 문제가 있습니다.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

답변

6

언제 전화 하시겠습니까? 첫 번째 호출 할 때 패널이 아직 렌더링되지 않았으므로 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

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

. 희망이 도움이됩니다. 당신이 애니메이션을하려고하는 하나의 뷰가있는 경우

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()를 사용할 필요가 없습니다. 자바 부분은 다음과 같습니다

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

을 다른 방법으로, getHeight() 올바른 높이를 반환, 함께 여러 뷰를 애니메이션을 처음 볼 수있는 위의 작업을 수행하고, 그래서 post runnable에 다음 뷰를 애니메이션해야하는 경우 그래서 같은 첫 번째보기의 :

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_decelerate_interpolator 그대로 accelerate_interpolator를 추가해야합니다.

+0

현재 보이지 않는 뷰를 이동해야하는 경우,'onCreate()'에서 높이를 계산해야합니다. 방법에 대해서는 [이 답변] (http://stackoverflow.com/a/10134260/1902059)을 참조하십시오. – willlma

관련 문제