Androidフラグメントとアニメーション


265

Honeycomb Gmailクライアントが使用するようなスライドをどのように実装すべきですか?

TransactionManagerフラグメントを追加および削除することでこれを自動的に処理できます。エミュレーターがスライドショーであるため、これをテストするのは少し難しいです:)

回答:


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.showft.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:不明なアニメーター名:translateが表示されました
Labeeb Panampullan、2011

3
slide_in_leftおよびrightで定義されたアニメーションが、古いアニメーション定義ではなく、一連のobjectAnimator定義を使用して構築されていることを確認してください。
Reto Meier、

7
それは大いに役立ちました。私は正しい軌道に乗っていたが、そこまで到達できなかった。他のリーダーの場合は、属性としてandroid:interpolatorを指定し、好きなものを指定することもできます( "@android:interpolator / linear"など)。デフォルトは「@android:interpolator / accelerate_decelerate」です。
デイブ・マクリーン

6
私は互換性APIでAPIレベル7をターゲットにしています。フラグメントをアニメーション化する方法はありますか?
ジャロッドスミス

5
あなたは次のように互換性ライブラリを使用して試すことができます@JarrodSmith NineOldAndroidsエクレアまでハニカムAPIを持参します。
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 2013

3
私は私のフラグメントに実装しようとしました。あなたが言ったように私はすべてを書きましたが、logcatは:unknow animator name translateと言っています。ちなみに、ナビゲーションドロワー(スライドメニュー)でフラグメントを呼び出しています
Zafer Celaloglu 14年

うまく機能しますが、ビルドツール21.1でこれをビルドすると、「無効なファイル名:小文字と数字([a-z0-9_。])のみを含める必要があります」というエラーが生成されることがわかりました。pop_enter.xmlとpop_exit.xmlの回答でファイル名を編集することをお勧めします。
2015年

素晴らしいソリューションで、戻るボタンを押すとうまくいきます。質問が1つだけあります。カスタムのbackButtonを作成する場合、[戻る]ボタンから動作を複製するためにどのコードを呼び出す必要がありますか?
Thomas Teilmann、2015年

1
あなたが戻ってする場合はトーマスは、あなたがこのフォームを実装する必要があります.setCustomAnimations(R.anim.pop_enter、R.anim.pop_exit、R.anim.enter、R.anim.exit)
アレックス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固有です。ところで、APIが持っている情報を共有していません。 android.Rの内容は、APIによって異なります。
steve moretz

@stevemoretz thaxs bro私はあなたの意見に同意しました..私は私の答えを修正して更新します...
Gowthaman M

5

私が変更したサポートライブラリは、フラグメントトランジションでのビューアニメーション(つまり<translate>, <rotate>)とオブジェクトアニメーター(つまり<objectAnimator>)の両方の使用をサポートしています。NineOldAndroidsで実装されています。詳細については、githubにある私のドキュメントを参照してください。


2

私に関しては、私はビューdiractionが必要です:

で->右からスワイプ

アウト->左にスワイプ

ここで私のために働くコード:

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

Androidは、これらのアニメーション(特に翻訳のもの)でトランジションをちらつかせているようです
Gabriel De Oliveira 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.