web-dev-qa-db-ja.com

フラグメントトランザクションアニメーション:スライドインおよびスライドアウト

フラグメント間のトランザクションをアニメーション化するためのいくつかのチュートリアルを確認しました。私はこのメソッドをアニメーションに使用しましたが、動作します:

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

しかし、アニメーションを反転させたいです。古いフラグメントは左にスライドし、新しいフラグメントは右にスライドしますが、R.animfileの値は私のスコープにとって有用ではないようです。

どうすればいいですか?

87
giozh

UPDATEAndroid 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%" Android:toXDelta="0%"
      Android:fromYDelta="0%" Android:toYDelta="0%"
      Android:duration="700"/>
</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%" Android:toXDelta="0%"
     Android:fromYDelta="0%" Android:toYDelta="0%"
     Android:duration="700" />
</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%"
      Android:fromYDelta="0%" Android:toYDelta="0%"
      Android:duration="700"/>
</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%"
     Android:fromYDelta="0%" Android:toYDelta="0%"
     Android:duration="700" />
</set>

USAGE(トランザクションでメソッドを呼び出す順序が重要であることに注意してください。replace、.commitを呼び出す前にアニメーションを追加してください):

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

アニメーションを断片的に処理する方法は3つあります。

遷移

したがって、組み込みの遷移のいずれかを使用する必要がある場合は、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"/>

複数のアニメーション

最後に、単一のトランザクションで複数のフラグメントアニメーションを開始することもできます。これにより、1つのフラグメントが上にスライドし、他のフラグメントが同時に下にスライドするという非常にクールな効果が得られます。

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にアクセスできます

注:-上記に問題がある可能性があるため、要件に応じてアニメーションを確認できます。

23
duggu

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();
3
live-love

これは私が使用する別のソリューションです:

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

クラスの使用法。以下に示すように、2つのフラグメント(リストフラグメントと詳細フラグメント)があるとします。

<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();_を使用して前のビューを取得できます。

2
COLD ICE

私は同じ問題を抱えています、私は簡単な解決策を使用しました

1)animフォルダーにsliding_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フォルダーにslide_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)フラグメントトランザクションsetCustomeAnimations()を次のようにアニメーション用に2つのカスタムxmlと2つのデフォルトxmlで使用するだけです。

 fragmentTransaction.setCustomAnimations(R.anim.sliding_in_left, R.anim.sliding_out_right, Android.R.anim.slide_in_left, Android.R.anim.slide_out_right );
1
Mayuri Shinde