안드로이드 조각 및 애니메이션


265

예를 들어 Honeycomb Gmail 클라이언트가 사용하는 슬라이딩 방식을 어떻게 구현해야합니까?

TransactionManagerFragments를 추가하고 제거하여 자동으로 처리 할 수 있습니다. 에뮬레이터가 슬라이드 쇼이기 때문에 테스트하기가 어렵습니다 :)

답변:


388

프래그먼트 간 전환에 애니메이션을 적용하거나 프래그먼트를 표시하거나 숨기는 프로세스에 애니메이션을 적용하려면을 사용하여을 Fragment Manager만듭니다 Fragment Transaction.

각 Fragment Transaction 내에서 각각 표시 및 숨기기에 사용될 인 / 아웃 애니메이션을 지정할 수 있습니다 (또는 바꾸기 사용시).

다음 코드는 한 조각을 밀고 다른 조각을 그 자리에 밀어 넣어 조각을 교체하는 방법을 보여줍니다.

FragmentTransaction ft = getFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);

DetailsFragment newFragment = DetailsFragment.newInstance();

ft.replace(R.id.details_fragment_container, newFragment, "detailFragment");

// Start the animated transition.
ft.commit();

단순히 호출 ft.show하거나 호출 ft.hide할 조각을 표시하거나 표시하거나 숨길 조각을 전달 하여 동일한 작업을 수행합니다 .

참고로 XML 애니메이션 정의는 objectAnimator태그를 사용합니다 . slide_in_left의 예는 다음과 같습니다.

<?xml version="1.0" encoding="utf-8"?>
<set>
  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x" 
    android:valueType="floatType"
    android:valueFrom="-1280"
    android:valueTo="0" 
    android:duration="500"/>
</set>

57
이 작업을 시도하면 RuntimeException : Unknown animator name : translate이 표시 됩니다.
Labeeb Panampullan

3
slide_in_left 및 right에 정의 된 애니메이션이 이전 애니메이션 정의가 아닌 objectAnimator 정의 세트를 사용하여 구성되어 있는지 확인하십시오.
Reto Meier

7
그것은 많은 도움이되었습니다. 나는 올바른 길을 가고 있었지만 거기까지는 가지 못했습니다. 다른 독자의 경우 좋아하는 것을 지정하여 속성 (예 : "@android : interpolator / linear")으로 android : interpolator를 속성으로 사용할 수도 있습니다. 기본값은 "@android : interpolator / accelerate_decelerate"입니다.
Dave MacLean

6
호환성 API로 API 레벨 7을 타겟팅하고 있습니다. 프래그먼트에 애니메이션을 적용 할 수있는 방법이 있습니까?
Jarrod Smith

5
당신은 같은 호환성 라이브러리를 사용하여 시도 할 수 있습니다 @JarrodSmith NineOldAndroids 에클 레어까지 허니 콤 API을 가지고.
Mr. S

249

지원 라이브러리를 사용할 필요가 없다면 Roman의 대답을 살펴보십시오 .

그러나 지원 라이브러리 를 사용하려면 아래에 설명 된대로 이전 애니메이션 프레임 워크를 사용해야합니다.

Retoblindstuff의 답변을 참조한 후 다음 코드가 작동했습니다.

조각을 다시 누르면 오른쪽 에서 미끄러 져 왼쪽으로 미끄러 져 나타납니다 .

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

순서가 중요합니다. 즉, setCustomAnimations()전에 전화해야 replace()애니메이션이 적용되지 않습니다!

다음으로이 파일들은 res / anim 폴더 안에 있어야 합니다.

enter.xml :

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

exit.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="-100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml :

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="-100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml :

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

애니메이션 지속 시간은 @android:integer/config_shortAnimTime다른 숫자 와 같은 기본값으로 변경할 수 있습니다 .

프래그먼트 교체 사이에 구성 변경 (예 : 회전)이 발생하면 뒤로 동작이 애니메이션되지 않습니다. 이것은 지원 라이브러리의 개정판 20에 여전히 존재 하는 문서화 된 버그 입니다.


47
이것은 단지 나를 구했다. 주문에 주의를 기울이는 것이 중요 합니다. 즉, replace () 전에 setCustomAnimations ()를 호출해야합니다.
Stephen Kidson

3
나는 당신이 언급 한대로 모든 것을 썼다. 그러나 logcat은 말한다 : 애니메이터 이름을 알지 못한다.이 문제를 어떻게 극복 할 수 있습니까? 그런데 나는 탐색 창 (슬라이딩 메뉴) 내 조각을 전화 했어
ZAFER Celaloglu

훌륭하게 작동하지만 빌드 도구 21.1로이를 빌드하면 "잘못된 파일 이름 : 소문자와 숫자 만 포함해야합니다 ([a-z0-9_.])"라는 오류가 발생합니다. pop_enter.xml 및 pop_exit.xml에 대한 답변에서 파일 이름을 편집하는 것이 좋습니다.
smichak

훌륭한 솔루션이며 뒤로 버튼을 누를 때 효과적입니다. 하나의 질문이 있습니다. 맞춤형 backButton을 만들려면 뒤로 버튼에서 동작을 복제하기 위해 어떤 코드를 호출해야합니까?
Thomas Teilmann

1
토마스 당신이 백업을 원한다면 .setCustomAnimations (R.anim.pop_enter, R.anim.pop_exit, R.anim.enter, R.anim.exit)
Alex Zaraos

26

훨씬 나은 솔루션이기 때문에 애니메이션 파일을 만드는 대신 이것을 사용하는 것이 좋습니다. Android Studio는 이미 새 XML 파일을 만들지 않고도 사용할 수있는 기본값 animation 을 제공 합니다. 애니메이션 이름은 android.R.anim.slide_in_leftandroid.R.anim.slide_out_right 이며 다음과 같이 사용할 수 있습니다.

fragmentTransaction.setCustomAnimations (android.R.anim.slide_in_left, android.R.anim.slide_out_right);

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();              
fragmentTransaction.setCustomAnimations(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
fragmentManager.addOnBackStackChangedListener(this);
fragmentTransaction.replace(R.id.frame, firstFragment, "h");
fragmentTransaction.addToBackStack("h");
fragmentTransaction.commit();

산출:

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


1
android.R ... "Android Studio는 기본 애니메이션을 제공합니다".Android 스튜디오에서는 Eclipse에서 작동하지 않을 수 있습니다 .android.R은 Android마다 다릅니다. android.R의 물건은 다른 API에서 다릅니다.
스티브 모 레츠

@stevemoretz thaxs bro 나는 당신의 요점에 동의했다. 나는 나의 대답을 수정하고 업데이트 할 것이다 ...
Gowthaman M

5

수정 된 지원 라이브러리 는 조각 전환에 View 애니메이션 (예 <translate>, <rotate>:) 및 객체 애니메이터 (예 :) 를 모두 사용할 수 있습니다 <objectAnimator>. NineOldAndroids 로 구현됩니다 . 자세한 내용은 github에 대한 내 설명서를 참조하십시오.


2

나에 관해서는보기 diraction이 필요합니다.

에서-> 오른쪽에서 스 와이프

out-> 왼쪽으로 스 와이프

여기 코드가 작동합니다.

slide_in_right.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate android:fromXDelta="50%p" android:toXDelta="0"
            android:duration="@android:integer/config_mediumAnimTime"/>
    <alpha android:fromAlpha="0.0" android:toAlpha="1.0"
            android:duration="@android:integer/config_mediumAnimTime" />
</set>

slide_out_left.xml

 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
    </set>

거래 코드 :

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}

안드로이드 (특히 사람 번역) 그 애니메이션으로 전환을 깜박 거리는 것 같다
가브리엘 드 올리베이라 Rohden

@GabrielDeOliveiraRohden 모든 케이스에있는 것은 아닙니다
Serg Burlaka

1

아래 방법으로 해결합니다

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.