setvisibility (view.Gone) 동안 간단한 애니메이션을 추가하는 Android


237

간단한 레이아웃을 디자인했습니다. 애니메이션없이 디자인을 마쳤지만 이제 텍스트 뷰 클릭 이벤트에서 애니메이션을 추가하고 싶습니다. 어떻게 사용하는지 모르겠습니다. 내 XML 디자인이 좋아 보였습니까? 모든 제안을 부탁드립니다.

내 XML

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16" >

<LinearLayout 
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#00DDA0"
    android:layout_weight="3" >
</LinearLayout>
 <TextView
        android:id="@+id/Information1"
        android:layout_width="match_parent"
        android:layout_height="1dp" 
        android:text="Child Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>

 <LinearLayout
     android:id="@+id/layout1"
     android:layout_width="fill_parent"
     android:layout_height="0dp"
     android:layout_weight="8.5"
     android:background="#BBBBBB"
     android:orientation="vertical" >

     <TextView
         android:id="@+id/textView1"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
 </LinearLayout>

  <TextView
        android:id="@+id/Information2"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Parent Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
  <LinearLayout 
          android:id="@+id/layout2"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView2"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
   <TextView
        android:id="@+id/Information3"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Siblings" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
   <LinearLayout 
          android:id="@+id/layout3"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView3"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
    <TextView
        android:id="@+id/Information4"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Teacher Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
    <LinearLayout 
          android:id="@+id/layout4"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView4"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
     <TextView
        android:id="@+id/Information5"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Grade Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
     <LinearLayout 
          android:id="@+id/layout5"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
     <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" />
      </LinearLayout>
      <TextView
        android:id="@+id/Information6"
        android:layout_width="match_parent"
        android:layout_height="0dp" 
        android:text="Health Information" 
        android:background="#0390BE"
        android:layout_weight="0.75"
        android:textColor="#FFFFFF"
        android:layout_gravity="center|fill_horizontal"/>
      <LinearLayout 
          android:id="@+id/layout6"
    android:layout_width="fill_parent"
    android:layout_height="0dp"
    android:orientation="vertical"
    android:background="#BBBBBB"
    android:layout_weight="8.5" >
    <TextView
         android:id="@+id/textView5"
         android:layout_width="match_parent"
         android:layout_height="match_parent"        
         android:text="TextView" 
         android:layout_weight="8.5" />
      </LinearLayout>

</LinearLayout>

내 자바

public class Certify_Info extends Activity {

    private static TextView tv2,tv3,tv5,tv6,tv4,tv1;
    private static LinearLayout l1,l2,l3,l4,l5,l6;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_certify__info);

        tv1=(TextView) findViewById(R.id.Information1);
        tv2=(TextView) findViewById(R.id.Information2);
        tv3=(TextView) findViewById(R.id.Information3);
        tv4=(TextView) findViewById(R.id.Information4);
        tv5=(TextView) findViewById(R.id.Information5);
        tv6=(TextView) findViewById(R.id.Information6); 

        l1=(LinearLayout) findViewById(R.id.layout1);
        l2=(LinearLayout) findViewById(R.id.layout2);
        l3=(LinearLayout) findViewById(R.id.layout3);
        l4=(LinearLayout) findViewById(R.id.layout4);
        l5=(LinearLayout) findViewById(R.id.layout5);
        l6=(LinearLayout) findViewById(R.id.layout6); 

        l2.setVisibility(View.GONE);
        l3.setVisibility(View.GONE); 
        l4.setVisibility(View.GONE); 
        l5.setVisibility(View.GONE);
        l6.setVisibility(View.GONE);

        tv1.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l1.setVisibility(View.VISIBLE);
            }
        });
        tv2.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l2.setVisibility(View.VISIBLE);
            }
        });
        tv3.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l3.setVisibility(View.VISIBLE);

            }
        });
        tv4.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.GONE);
                l4.setVisibility(View.VISIBLE); 
            }
        });
        tv5.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l6.setVisibility(View.GONE);
                l5.setVisibility(View.VISIBLE); 
            }
        });
        tv6.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                l1.setVisibility(View.GONE);
                l2.setVisibility(View.GONE);
                l3.setVisibility(View.GONE); 
                l4.setVisibility(View.GONE); 
                l5.setVisibility(View.GONE);
                l6.setVisibility(View.VISIBLE);
            }
        });

    }
}

답변:


706

애니메이션을 추가하기 위해 두 가지를 할 수 있습니다. 먼저 안드로이드가 레이아웃 변경에 애니메이션을 적용 할 수 있습니다. 그렇게하면 뷰 가시성 또는 뷰 위치 변경과 같이 레이아웃에서 무언가를 변경할 때마다 안드로이드가 자동으로 페이드 / 전환 애니메이션을 생성합니다. 그 세트를 사용하려면

android:animateLayoutChanges="true"

레이아웃의 루트 노드에서.

두 번째 옵션은 수동으로 애니메이션을 추가하는 것입니다. 이를 위해 Android 3.0 (Honeycomb)에 도입 된 새로운 애니메이션 API를 사용하는 것이 좋습니다. 몇 가지 예를들 수 있습니다.

이것은 사라집니다 View:

view.animate().alpha(0.0f);

이것은 다시 사라집니다.

view.animate().alpha(1.0f);

View높이만큼 아래로 이동합니다 .

view.animate().translationY(view.getHeight());

이것은 View다른 곳으로 이동 한 후 시작 위치로 돌아갑니다 .

view.animate().translationY(0);

setDuration()애니메이션 지속 시간을 설정할 수도 있습니다 . 예를 들어, 이것은 View2 초에 걸쳐 사라집니다 .

view.animate().alpha(0.0f).setDuration(2000);

또한 원하는만큼 애니메이션을 결합 할 수 있습니다. 예를 들어,이 애니메이션은 페이드 아웃 View되고 0.3 초 ​​동안 동시에 아래로 이동합니다.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300);

또한 애니메이션에 리스너를 할당하고 모든 종류의 이벤트에 반응 할 수 있습니다. 애니메이션이 시작될 때, 끝나거나 반복 될 때와 같이. 추상 클래스 AnimatorListenerAdapter를 사용하면 모든 콜백을 AnimatorListener한 번 에 구현할 필요는 없지만 필요한 콜백 만 구현할 필요는 없습니다. 이것은 코드를 더 읽기 쉽게 만듭니다. 예를 들어 다음 코드 View는 0.3 초 ​​(300 밀리 초) 동안 높이가 아래로 이동하며 애니메이션이 완료되면 가시성이로 설정됩니다 View.GONE.

view.animate()
        .translationY(view.getHeight())
        .alpha(0.0f)
        .setDuration(300)
        .setListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                view.setVisibility(View.GONE);
            }
        });

6
@Natix 나는 그 슈퍼 콜 리던던트를 호출하지 않을 것입니다. 아무 것도 잘못 편집하지 마십시오.
Xaver Kapeller

5
좋지만 그 반대는 왜 제대로 작동하지 않습니까? view.setVisibility (View.VISIBLE); 알파 (1.0F)와 함께, ... 100 패딩 상단에 표시
대인 수수

15
가시성을 설정하기 전에 애니메이션을 지워야합니다 >> view.clearAnimation(); view.setVisibility(View.GONE);그렇지 않으면 레이아웃이 보이지 않고 사라지지 않습니다.
Eftekhari

2
@Eftekhari 리소스를 많이 사용하지는 않습니다. 최신 Android 버전을 사용하지만 메모리가 부족하거나 그래픽 칩이 불량한 구형 휴대 전화보다 지연이 발생할 수 있습니다. 그리고 나는 새로운 도서관에 대해 이야기하고 있지 않습니다. 애니메이터는 네이티브입니다. 그들은 안드로이드 프레임 워크의 일부입니다. 5 년 전에 출시되었으며 현재 모든 장치의 97.9 %가이를 지원합니다. 애니메이터를 사용하지 않거나 최소한 ViewCompat.animate()지원 라이브러리의 일부이며 최신 버전에서는 애니메이터를 사용하고 Android 3.0 이하에서는 애니메이션보기 를 사용할 이유가 없습니다 .
Xaver Kapeller

1
그러나 모든 기기의 97.9 %가 Android 4.0 이상인 경우의 사용 사례가 많지 않습니다 ViewCompat.animate().
Xaver Kapeller

70

Visibility변경 사항 에 애니메이션을 적용하는 가장 쉬운 방법 Transition API은 지원 (androidx) 패키지에서 사용 가능한 것을 사용 하는 것입니다. TransitionManager.beginDelayedTransition메소드를 호출 한 다음보기의 가시성을 변경하십시오. 같은 몇 가지 기본 전환이 있습니다 Fade, Slide.

import androidx.transition.TransitionManager;
import androidx.transition.Transition;
import androidx.transition.Fade;

private void toggle() {
    Transition transition = new Fade();
    transition.setDuration(600);
    transition.addTarget(R.id.image);

    TransitionManager.beginDelayedTransition(parent, transition);
    image.setVisibility(show ? View.VISIBLE : View.GONE);
}

애니메이션 뷰의 parent부모 ViewGroup는 어디에 있습니까 ? 결과:

여기에 이미지 설명을 입력하십시오

Slide전환 결과는 다음과 같습니다 .

import androidx.transition.Slide;

Transition transition = new Slide(Gravity.BOTTOM);

여기에 이미지 설명을 입력하십시오

다른 것이 필요한 경우 사용자 지정 전환을 작성하기 쉽습니다. 여기 CircularRevealTransition다른 답변으로 쓴 예가 있습니다. CircularReveal 애니메이션으로보기를 표시하고 숨 깁니다.

Transition transition = new CircularRevealTransition();

여기에 이미지 설명을 입력하십시오

android:animateLayoutChanges="true"옵션은 동일한 작업을 수행하며 자동 전환을 전환으로 사용합니다.


@TouhidulIslam no. 이 클래스는 androidx 패키지로 제공됩니다. 모든 것이 이전 버전과 호환됩니다
ashakirov

2
뷰 그룹을 확장 / 축소하는 것은 어떻습니까?
TheRealChx101

여러 가지를 할 수 있습니까 beginDelayedTransition?
Jeongbebs

26

링크를 확인 하십시오. L2R, R2L, T2B, B2T 애니메이션과 같은 애니메이션을 허용합니다.

이 코드는 왼쪽에서 오른쪽으로 애니메이션을 보여줍니다

TranslateAnimation animate = new TranslateAnimation(0,view.getWidth(),0,0);
animate.setDuration(500);
animate.setFillAfter(true);
view.startAnimation(animate);
view.setVisibility(View.GONE);

R2L에서 사용하려면 다음을 사용하십시오.

TranslateAnimation animate = new TranslateAnimation(0,-view.getWidth(),0,0);

위에서 아래로

TranslateAnimation animate = new TranslateAnimation(0,0,0,view.getHeight());

그 반대의 경우도 마찬가지입니다.


8
뷰가 원래 위치에서 이동합니다.
Relm

24

이 줄을 xml 부모 레이아웃에 추가하십시오.

 android:animateLayoutChanges="true"

레이아웃은 다음과 같습니다

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true"
    android:longClickable="false"
    android:orientation="vertical"
    android:weightSum="16">

    .......other code here

    </LinearLayout>

이것은 나를 위해 일했습니다. 내 설정은 제약 조건 레이아웃을 루트보기로 사용합니다. 뷰가 View.VISIBLE로 설정되면 애니메이션이 표시됩니다
EdgeDev

매우 간단하고 우아한 솔루션
Naveed Ahmad

11

@Xaver Kapeller의 답변을 바탕으로 새로운보기가 화면에 나타날 때 스크롤 애니메이션을 만드는 방법을 알아 냈습니다.

이 상태에서옵니다 :

  • 단추
  • 마지막 버튼

  • 단추
  • 버튼 1
  • 버튼 2
  • 버튼 3
  • 버튼 4
  • 마지막 버튼

그 반대.

따라서 사용자가 첫 번째 버튼을 클릭하면 페이드 애니메이션을 사용하여 "버튼 1", "버튼 2", "버튼 3"및 "버튼 4"요소가 나타나고 "마지막 단추"요소가 끝까지 아래로 이동합니다. 레이아웃의 높이도 변경되어 스크롤보기를 올바르게 사용할 수 있습니다.

다음은 애니메이션으로 요소를 표시하는 코드입니다.

private void showElements() {
    // Precondition
    if (areElementsVisible()) {
        Log.w(TAG, "The view is already visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    // the alpha as 0.0. Otherwise the animation won't be shown
    mHiddenLinearLayout.setVisibility(View.VISIBLE);
    mHiddenLinearLayout.setAlpha(0.0f);
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(1.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    super.onAnimationEnd(animation);
                    updateShowElementsButton();
                    mHiddenLinearLayout.animate().setListener(null);
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(mHiddenLinearLayoutHeight);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight() + mHiddenLinearLayoutHeight;
}

그리고 이것은 애니메이션 요소를 숨기는 코드입니다.

private void hideElements() {
    // Precondition
    if (!areElementsVisible()) {
        Log.w(TAG, "The view is already non-visible. Nothing to do here");
        return;
    }

    // Animate the hidden linear layout as visible and set
    mHiddenLinearLayout
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .alpha(0.0f)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    Log.v(TAG, "Animation ended. Set the view as gone");
                    super.onAnimationEnd(animation);
                    mHiddenLinearLayout.setVisibility(View.GONE);
                    // Hack: Remove the listener. So it won't be executed when
                    // any other animation on this view is executed
                    mHiddenLinearLayout.animate().setListener(null);
                    updateShowElementsButton();
                }
            })
    ;

    mLastButton
            .animate()
            .setDuration(ANIMATION_TRANSITION_TIME)
            .translationY(0);

    // Update the high of all the elements relativeLayout
    LayoutParams layoutParams = mAllElementsRelativeLayout.getLayoutParams();

    // TODO: Add vertical margins
    layoutParams.height = mLastButton.getHeight();
}

애니메이션을 숨기는 방법에는 간단한 해킹이 있습니다. 애니메이션 리스너 mHiddenLinearLayout에서 다음을 사용하여 리스너 자체를 제거해야했습니다.

mHiddenLinearLayout.animate().setListener(null);

애니메이션 리스너가 뷰에 연결되면 다음에이 뷰에서 애니메이션이 실행될 때 리스너도 실행되기 때문입니다. 이것은 애니메이션 리스너의 버그 일 수 있습니다.

프로젝트의 소스 코드는 GitHub에 있습니다 : https://github.com/jiahaoliuliu/ViewsAnimated

행복한 코딩!

업데이트 : 뷰에 연결된 리스너의 경우 애니메이션이 끝난 후 제거해야합니다. 이것은 사용하여 수행

view.animate().setListener(null);

이것은 최고의 답변입니다
Naveen Kumar M

1
view.animate().setListener(null);문은 내 일을 구했습니다. 이것은 분명히 버그 인 것 같습니다.
Michal Vician

@MichalVician 다행 이네요!
jiahao

8

이런 식으로 메뉴를 표시하거나 숨길 수있었습니다.

MenuView.java (FrameLayout 확장)

private final int ANIMATION_DURATION = 500;

public void showMenu()
{
    setVisibility(View.VISIBLE);
    animate()
            .alpha(1f)
            .setDuration(ANIMATION_DURATION)
            .setListener(null);
}

private void hideMenu()
{
    animate()
            .alpha(0f)
            .setDuration(ANIMATION_DURATION)
            .setListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(View.GONE);
                }
            });
}

출처

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.