조각 트랜잭션 애니메이션 : 슬라이드 인 및 슬라이드 아웃


104

조각 간의 애니메이션 트랜잭션에 대한 자습서를 확인했습니다. 이 방법을 애니메이션에 사용했으며 작동합니다.

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

하지만이 애니메이션을 반전하고 싶습니다. 오래된 조각은 왼쪽으로, 새 조각은 오른쪽으로 미끄러지지 만 R.anim파일 값은 내 범위에 유용 하지 않은 것 같습니다.

내가 어떻게 해?


제 생각 override key_code==back_key_press에는 두 번째 단편에서 시도해 볼 수 있습니다.
Nitin Misra

나 자신을 잘 벗어나지 못할 수도 있습니다. 조각 스왑, 이전 조각이 왼쪽에 슬라이드되고 새 조각이 오른쪽에서 들어올 때 원합니다. 이 코드를 사용하면 동작이 반대입니다
giozh 2014 년

1
여기
Carsten

답변:


278

업데이트 Android v19 +의 경우 @Sandra를 통해이 링크참조하십시오.

자신 만의 애니메이션을 만들 수 있습니다. 애니메이션 XML 파일 배치res > anim

enter_from_left.xml

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

enter_from_right.xml

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

exit_to_left.xml

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

exit_to_right.xml

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

짧은 애니메이션 시간으로 기간을 변경할 수 있습니다.

android:duration="@android:integer/config_shortAnimTime"

또는 긴 애니메이션 시간

android:duration="@android:integer/config_longAnimTime" 

USAGE (트랜잭션에서 메소드를 호출하는 순서가 중요합니다. .replace, .commit을 호출하기 전에 애니메이션을 추가하십시오) :

FragmentTransaction transaction = supportFragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
transaction.replace(R.id.content_frame, fragment);
transaction.addToBackStack(null);
transaction.commit();

29
프래그먼트를 교체 할 때 다음과 같은 xml 애니메이션을 사용하면됩니다. 즉, fragmentTransaction.setCustomAnimations (R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right); fragmentTransaction.replace (R.id.content_frame, fragDettRisorsa); fragmentTransaction.addToBackStack (null); fragmentTransaction.commit ();
moondroid

11
그 말을 알 수없는 애니메이터 이름 : 번역
Hirak Chhatbar

9
작동하지 않습니다 ... "java.lang.RuntimeException : 알 수없는 애니메이터 이름 : 번역"이 발생했습니다. 이 솔루션은 저에게 효과적이었습니다. trickyandroid.com/fragments-translate-animation
Ataru

27
700제 생각에는 그러한 애니메이션의 지속 시간 이 약간 많습니다. Android 프레임 워크에는 3 개의 타이밍 사전 설정이 있습니다. android:duration="@android:integer/config_longAnimTime", android:duration="@android:integer/config_mediumAnimTime"android:duration="@android:integer/config_shortAnimTime", 이는 500, 400 및 200에 해당합니다. 단위는 밀리 초라고 생각하지만 확실하지 않습니다.
Krøllebølle

6
지원 조각 (android.support.v4.app.Fragment) 사용하는 경우에만 작동합니다
아비브 Shabat

37

프래그먼트 애니메이션에는 세 가지 방법이 있습니다.

전환

따라서 내장 된 Transitions 중 하나를 사용해야하며 setTranstion () 메서드를 사용합니다.

getSupportFragmentManager()
        .beginTransaction()
        .setTransition( FragmentTransaction.TRANSIT_FRAGMENT_OPEN )
        .show( m_topFragment )
        .commit()

커스텀 애니메이션

setCustomAnimations () 메서드를 사용하여 애니메이션을 사용자 지정할 수도 있습니다.

getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations( R.anim.slide_up, 0, 0, R.anim.slide_down)
        .show( m_topFragment )
        .commit()

slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="translationY"
        android:valueType="floatType"
        android:valueFrom="1280"
        android:valueTo="0"
        android:duration="@android:integer/config_mediumAnimTime"/>

slide_down.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:propertyName="translationY"
        android:valueType="floatType"
        android:valueFrom="0"
        android:valueTo="1280"
        android:duration="@android:integer/config_mediumAnimTime"/>

여러 애니메이션

마지막으로 단일 트랜잭션에서 여러 조각 애니메이션을 시작하는 것도 가능합니다. 이것은 한 조각이 위로 미끄러지고 다른 조각이 동시에 아래로 미끄러지는 매우 멋진 효과를 허용합니다 :

getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations( R.anim.abc_slide_in_top, R.anim.abc_slide_out_top ) // Top Fragment Animation
        .show( m_topFragment )
        .setCustomAnimations( R.anim.abc_slide_in_bottom, R.anim.abc_slide_out_bottom ) // Bottom Fragment Animation
        .show( m_bottomFragment )
        .commit()

자세한 내용은 URL을 방문하십시오.

참고 :- 위의 문제가있을 수 있으므로 요구 사항에 따라 애니메이션을 확인할 수 있습니다.


1
절대 하드 코딩 된 값을 사용하고 있습니다. 고해상도 디스플레이를 위해 이전 조각이 화면 중앙에서 사라집니다.
TheLibrarian

이 @TheLibrarianCz 단지 예입니다
duggu

1
그렇고 그렇지 않습니다.
TheLibrarian

어떤 사람은 위의 예에서 숟가락으로 먹이를 주거나 예를 통해 얻을 수있는 교훈을 받기를 원합니다.
duggu

m_topFragment 변수에 무엇인가
왕자

6

나는 같은 문제가 있으며 간단한 해결책을 사용했습니다.

1) anim 폴더에 liding_out_right.xml 생성

  <?xml version="1.0" encoding="utf-8"?>
    <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>

2) anim 폴더에 liding_in_left.xml 생성

<?xml version="1.0" encoding="utf-8"?>
<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>

3) 다음과 같이 애니메이션에 대해 두 개의 사용자 지정 xml과 두 개의 기본 xml이있는 조각 트랜잭션 setCustomeAnimations ()를 사용하기 만하면됩니다.

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

5

slide_in_down.xml

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

slide_in_up.xml

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

slide_out_down.xml

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

slide_out_up.xml

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

방향 = 아래

            activity.getSupportFragmentManager()
                    .beginTransaction()
                    .setCustomAnimations(R.anim.slide_out_down, R.anim.slide_in_down)
                    .replace(R.id.container, new CardFrontFragment())
                    .commit();

방향 = 위로

           activity.getSupportFragmentManager()
                    .beginTransaction()
                    .setCustomAnimations(R.anim.slide_in_up, R.anim.slide_out_up)
                    .replace(R.id.container, new CardFrontFragment())
                    .commit();

2

이것은 내가 사용하는 또 다른 솔루션입니다.

public class CustomAnimator {
    private static final String TAG = "com.example.CustomAnimator";

    private static Stack<AnimationEntry> animation_stack    = new Stack<>();

    public static final int                 DIRECTION_LEFT  = 1;
    public static final int                 DIRECTION_RIGHT = -1;
    public static final int                 DIRECTION_UP    = 2;
    public static final int                 DIRECTION_DOWN  = -2;

    static class AnimationEntry {
        View in;
        View    out;
        int     direction;
        long    duration;
    }

    public static boolean hasHistory() {
        return !animation_stack.empty();
    }

    public static void reversePrevious() {
        if (!animation_stack.empty()) {
            AnimationEntry entry = animation_stack.pop();
            slide(entry.out, entry.in, -entry.direction, entry.duration, false);
        }
    }

    public static void clearHistory() {
        animation_stack.clear();
    }

    public static void slide(final View in, View out, final int direction, long duration) {
        slide(in, out, direction, duration, true);
    }

    private static void slide(final View in, final View out, final int direction, final long duration, final boolean save) {

        ViewGroup in_parent = (ViewGroup) in.getParent();
        ViewGroup out_parent = (ViewGroup) out.getParent();

        if (!in_parent.equals(out_parent)) {
            return;
        }

        int parent_width = in_parent.getWidth();
        int parent_height = in_parent.getHeight();

        ObjectAnimator slide_out;
        ObjectAnimator slide_in;

        switch (direction) {
            case DIRECTION_LEFT:
            default:
                slide_in = ObjectAnimator.ofFloat(in, "translationX", parent_width, 0);
                slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, -out.getWidth());
                break;
            case DIRECTION_RIGHT:
                slide_in = ObjectAnimator.ofFloat(in, "translationX", -out.getWidth(), 0);
                slide_out = ObjectAnimator.ofFloat(out, "translationX", 0, parent_width);
                break;
            case DIRECTION_UP:
                slide_in = ObjectAnimator.ofFloat(in, "translationY", parent_height, 0);
                slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, -out.getHeight());
                break;
            case DIRECTION_DOWN:
                slide_in = ObjectAnimator.ofFloat(in, "translationY", -out.getHeight(), 0);
                slide_out = ObjectAnimator.ofFloat(out, "translationY", 0, parent_height);
                break;
        }

        AnimatorSet animations = new AnimatorSet();
        animations.setDuration(duration);
        animations.playTogether(slide_in, slide_out);
        animations.addListener(new Animator.AnimatorListener() {

            @Override
            public void onAnimationCancel(Animator arg0) {
            }

            @Override
            public void onAnimationEnd(Animator arg0) {
                out.setVisibility(View.INVISIBLE);
                if (save) {
                    AnimationEntry ae = new AnimationEntry();
                    ae.in = in;
                    ae.out = out;
                    ae.direction = direction;
                    ae.duration = duration;
                    animation_stack.push(ae);
                }
            }

            @Override
            public void onAnimationRepeat(Animator arg0) {
            }

            @Override
            public void onAnimationStart(Animator arg0) {
                in.setVisibility(View.VISIBLE);
            }
        });
        animations.start();
    }
}

수업의 사용법. 아래와 같이 두 개의 조각 (목록 및 세부 정보 조각)이 있다고 가정 해 보겠습니다.

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

    <FrameLayout
        android:id="@+id/list_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

    <FrameLayout
        android:id="@+id/details_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone" />
</FrameLayout>

용법

View details_container = findViewById(R.id.details_container);
View list_container = findViewById(R.id.list_container);
// You can select the direction left/right/up/down and the duration
CustomAnimator.slide(list_container, details_container,CustomAnimator.DIRECTION_LEFT, 400);

CustomAnimator.reversePrevious();사용자가 뒤로 눌렀을 때 이전보기를 가져 오는 기능 을 사용할 수 있습니다 .


1
Android의 Fragments를 사용하고 있습니까? =)) 사용자 정의 조각 관리보기 기반 시스템을 사용하는 것 같아
키스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.