2011-04-08 4 views
3

주 레이아웃의 일부인 사용자 지정 검색 패널이 있습니다. 대부분의 경우 패널은 숨겨져 있습니다. 나는 패널에 나타나는/사라지는 애니메이션을 추가하고 싶다. 여기에 단순화 된 레이아웃 발췌 한 것입니다GONE 애니메이션 작업을 쉽게 수행하는 방법

<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 
    <RelativeLayout 
     android:id="@+id/layoutSearch" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:visibility="gone" > 
     <EditText 
      android:id="@+id/editSearch" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" /> 
     <<Other inner views to be animated>> 
    </RelativeLayout> 
    <<Other views, which should not be affected by the animation>> 
</LinearLayout> 

는 시도는 1 : 나는 애니메이션 리소스를 추가하고 XML에서이 라인으로 @ 아이디/layoutSearch에 첨부 :

android:layoutAnimation="@anim/search_in_layout" 

ANIM/search_in.xml :

<translate 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/overshoot_interpolator" 
    android:fromYDelta="-100%p" 
    android:toYDelta="0" 
    android:duration="@android:integer/config_longAnimTime" /> 

ANIM/search_in_layout.xml :

<layoutAnimation 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:animation="@anim/search_in" /> 

애니메이션은 정상적으로 작동하지만 패널이 나타나는 경우에만 작동합니다.

mSearchLayout.setVisibility(View.GONE); 

시도 2 ​​ : 나는 그것을 숨길 때 패널은 애니메이션없이 한 순간에 사라 내가 애니메이션 대상 매개 변수는 현재 패널의 위치를 ​​일치로 위의 솔루션이 작동하지 않는 것 같아요. 좋아, 나는 anim/search_out.xml과 anim/search_out_layout.xml이라는 두 개의 애니메이션 리소스를 추가로 만들었다. 유일한 차이점은 "YDelta"및 "YDelta"값으로 교환되고 업데이트 된 "android : animation"값입니다. 그럼이 코드에서 리소스를로드하고이 같은 @ 아이디/layoutSearch로 설정합니다

LayoutAnimationController controller = 
    AnimationUtils.loadLayoutAnimation(this, R.anim.search_out_layout); 
mSearchLayout.setLayoutAnimation(controller); 

은 "밖으로"애니메이션은 setLayoutAnimation의 호출에 트리거(). 애니메이션이 끝나면 "out"애니메이션 전에 있던 화면의 원래 위치로 검색 패널이 돌아갑니다. setLayoutAnimation() 직후에 mSearchLayout.setVisibility (View.GONE)를 호출하려고하면 애니메이션이 표시되지 않고 패널이 한 번에 사라집니다.

시도해보십시오. 3 : 코드에 애니메이션을 작성한 다음 리스너를 설정해야한다고 생각합니다. 그런 다음 애니메이션 재생 후 패널을 숨기려면 onAnimationEnd() 핸들러에서 mSearchLayout.setVisibility (View.GONE)를 호출해야합니다. 나는 아직 이것을 시도하지 않았다. 복잡한 일이라고 생각합니다.

내가 뭔가 중요한 것을 놓친 것 같아. GONE 애니메이션을 약간 쉽게 구현할 수있는 방법이 있습니까?

답변

4

시도해보기 3 : 코드에서 애니메이션을 생성 한 다음 리스너를 설정해야한다고 생각합니다. 그런 다음 애니메이션 재생 후 패널을 숨기려면 onAnimationEnd() 핸들러에서 mSearchLayout.setVisibility (View.GONE)를 호출해야합니다. 나는 아직 이것을 시도하지 않았다. 복잡한 일이라고 생각합니다.

여러분이해야 할 일이며 실제로 달성하기가 어렵지 않습니다.

샘플 코드 :

public class YourClass extends Foo implements AnimationListener { 

    //... 

    @Override 
    public void onAnimationEnd(Animation a) { 
     // Do stuff. 
    } 

    @Override 
    public void onAnimationRepeat(Animation a) {  
    } 

    @Override 
    public void onAnimationStart(Animation a) { 
    } 

} 
+0

"아웃"애니메이션 작업을 만드는 더 쉬운 방법은 없습니다. 고맙습니다. – borisstr

+1

애니메이션 끝 부분에서 성가신 플래시없이이 작업을 수행하는 방법을 찾았는지 궁금합니다.보기가 GONE이므로보기가 다시 출력됩니다. – num1

+1

View에 인수를 취하도록 생성자를 추가하는 것은 백만 번 반복 할 필요가없는 좋은 방법입니다. 그런 다음 a.setAnimationListener (new MyAnimationListener (v));로 원하는대로 적용 할 수 있습니다. 단, 각 애니메이션은 단일 뷰에 묶여 있어야합니다. –

2

GONE에보기를 설정 효과적으로 레이아웃에서 제거합니다. 대신 필요한 경우 애니메이션이 완료된 후 INVISIBLE으로 설정하고 GONE으로 설정해야합니다.

+0

답변 해 주셔서 감사합니다. 나는 INVISIBLE을 설정하려했다. 그것이 할 지점이 없다고 보입니다. 여전히 레이아웃 애니메이션과 청취자를 코드에 설치해야합니다. 애니메이션은 setLayoutAnimation()에서 시작되며 INVISIBLE을 설정할 필요가 없습니다. 이것은 매우 이상한데, "in"애니메이션은 코드의 한 줄을 필요로하지 않습니다 ... – borisstr

+0

이 방법은 **보기 ** 표시 또는 숨기기, 나는 생각하지 않습니다 ** ViewGroup ** 작업, 조셉 얼 (Joseph-Earl)에게 감사드립니다. – VinceStyling

4

재생 후 애니메이션을 유지하려면 애니메이션 클래스의에 setFillAfter()를 호출해야합니다.

RelativeLayout layout = (RelativeLayout) findViewById(R.id.layoutSearch); 
Animation a = AnimationUtils.loadAnimation(this, R.anim.push_down); 
a=setFillAfter(true); 
layout.setLayoutAnimation(new LayoutAnimationController(a)); 
layout.startLayoutAnimation(); 
7

다음은이 문제를 해결 한 방법입니다.

을 설정하면 다음과 같은 버그로 이어질 것 애니메이션의setFillAfter을 setFillBefore 있습니다! Issue 5272: View with visibility View.GONE still generates touch events http://code.google.com/p/android/issues/detail?id=5272

파일 : MyWebViewActivity.java

private View mBottomOverlay; 
private View mTopOverlay; 
private boolean mControlsOverlayVisible; 
private Animation mSlideBottomUpAnimation; 
private Animation mSlideBottomDownAnimation; 
private Animation mSlideTopDownAnimation; 
private Animation mSlideTopUpAnimation; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.reader_layout); 

    // load the overlay resources 
    mTopOverlay = findViewById(R.id.reader_overlay_top_toolbar); 
    mBottomOverlay = findViewById(R.id.reader_overlay_bottom_toolbar); 

    initAnimations(); 
} 

private void initAnimations() { 

    final AnimationListener makeTopGone = new AnimationListener() { 

     @Override 
     public void onAnimationStart(Animation animation) {} 

     @Override 
     public void onAnimationRepeat(Animation animation) {} 

     @Override 
     public void onAnimationEnd(Animation animation) { 
      Log.d(TAG, "onAnimationEnd - makeTopGone"); 
      mTopOverlay.setVisibility(View.GONE); 
     } 
    }; 

    final AnimationListener makeBottomGone = new AnimationListener() { 

     @Override 
     public void onAnimationStart(Animation animation) {} 

     @Override 
     public void onAnimationRepeat(Animation animation) { 
     } 

     @Override 
     public void onAnimationEnd(Animation animation) { 
      Log.d(TAG, "onAnimationEnd - makeBottomGone"); 
      mBottomOverlay.setVisibility(View.GONE); 
     } 
    }; 

    final AnimationListener makeTopVisible = new AnimationListener() { 

     @Override 
     public void onAnimationStart(Animation animation) { 
      Log.d(TAG, "onAnimationStart - makeTopVisible"); 
      mTopOverlay.setVisibility(View.VISIBLE); 
     } 

     @Override 
     public void onAnimationRepeat(Animation animation) {} 

     @Override 
     public void onAnimationEnd(Animation animation) {} 
    }; 

    final AnimationListener makeBottomVisible = new AnimationListener() { 

     @Override 
     public void onAnimationStart(Animation animation) { 
      Log.d(TAG, "onAnimationStart - makeBottomVisible"); 
      mBottomOverlay.setVisibility(View.VISIBLE); 
     } 

     @Override 
     public void onAnimationRepeat(Animation animation) {} 

     @Override 
     public void onAnimationEnd(Animation animation) {} 
    }; 

    mSlideTopUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_up); 
    mSlideBottomDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_down); 
    mSlideTopUpAnimation.setAnimationListener(makeTopGone); 
    mSlideBottomDownAnimation.setAnimationListener(makeBottomGone); 

    mSlideTopDownAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_top_down); 
    mSlideBottomUpAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom_up); 
    mSlideTopDownAnimation.setAnimationListener(makeTopVisible); 
    mSlideBottomUpAnimation.setAnimationListener(makeBottomVisible); 
} 

private void hideControlOverlays() { 
    Log.d(TAG, "hideControlOverlays"); 
    mTopOverlay.startAnimation(mSlideTopUpAnimation); 
    mBottomOverlay.startAnimation(mSlideBottomDownAnimation); 
    mControlsOverlayVisible = false; 
} 

private void showControlOverlays() { 
    Log.d(TAG, "showControlOverlays"); 
    mTopOverlay.startAnimation(mSlideTopDownAnimation); 
    mBottomOverlay.startAnimation(mSlideBottomUpAnimation); 
    mControlsOverlayVisible = true; 
} 

파일 : /res/layout/reader_layout.xml

<?xml version="1.0" encoding="utf-8"?> 
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/reader_layout" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" > 

    <WebView 
     android:id="@+id/webview" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" /> 

    <FrameLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/reader_overlay_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" > 

     <LinearLayout 
      android:id="@+id/reader_overlay_top_toolbar" 
      android:layout_width="fill_parent" 
      android:layout_height="140dp" 
      android:background="#80000000" > 

      <include layout="@layout/toolbar_top" /> 
     </LinearLayout> 

     <LinearLayout 
      android:id="@+id/reader_overlay_bottom_toolbar" 
      android:layout_width="fill_parent" 
      android:layout_height="140dp" 
      android:layout_gravity="bottom" 
      android:background="#80000000" 
      android:orientation="horizontal" > 

      <include layout="@layout/toolbar_bottom_left" /> 
     </LinearLayout> 
    </FrameLayout> 
</FrameLayout> 

파일 :/고해상도/ANIM /slide_bottom_down.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fillEnabled="true" 
    android:interpolator="@android:anim/accelerate_interpolator" > 
    <translate 
     android:duration="@android:integer/config_shortAnimTime" 
     android:fromYDelta="0" 
     android:toYDelta="100%" /> 
</set> 

파일 : /res/anim/slide_bottom_up.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_interpolator" > 
    <translate 
     android:duration="@android:integer/config_shortAnimTime" 
     android:fromYDelta="100%" 
     android:toYDelta="0" /> 
</set> 

파일 : /res/anim/slide_top_down.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:interpolator="@android:anim/accelerate_interpolator" > 
    <translate 
     android:duration="@android:integer/config_shortAnimTime" 
     android:fromYDelta="-100%" 
     android:toYDelta="0" /> 
</set> 

파일 :/res/anim/slide_top_up.xml

<?xml version="1.0" encoding="utf-8"?> 
<set xmlns:android="http://schemas.android.com/apk/res/android" 
    android:fillEnabled="true" 
    android:interpolator="@android:anim/accelerate_interpolator" > 
    <translate 
     android:duration="@android:integer/config_shortAnimTime" 
     android:fromYDelta="0" 
     android:toYDelta="-100%" /> 
</set> 
+0

hideControlOverlays() 및 showControlOverlays() 함수를 호출 할 때/어디에서 호출 할 지 말해 줄 수 있습니까? 비슷한 것을 개발하려고합니다. 당신의 대답은 정말 도움이 될 것입니다. 감사합니다 – CuriousCoder

+0

예를 들어보기 onTouch 또는 onClick 수신기에서 showControlsOverlay() 메서드를 호출 할 수 있습니다. hideControlsOverlay() 메서드는 다른 onTouch 또는 onClick 핸들러에서 호출 할 수도 있고 지연된 실행 가능을 설정하여 몇 초 후에 호출하여 사용자 상호 작용없이 자동으로 오버레이를 닫을 수 있습니다. –

+0

고마워, 잘 했어. 아주 좋은 해결책. +1 – CuriousCoder

관련 문제