web-dev-qa-db-ja.com

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

たとえばHoneycomb Gmailクライアントが使用するようなスライドをどのように実装する必要がありますか?

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

256
alexanderblom

フラグメント間の遷移をアニメートする、またはフラグメントを表示または非表示にするプロセスをアニメートするには、Fragment Managerを使用して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>
373
Reto Meier

サポートライブラリを使う必要がなければ、 Roman's answerをご覧ください。

しかし、サポートライブラリを使用したい場合は、以下に説明するように古いアニメーションフレームワークを使用する必要があります。

Reto'sblindstuff's の回答を調べた後、次のようなコードが動作するようになりました。

フラグメントは右側からスライドイン表示され左側にスライドアウト戻るを押すと.

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や他の数値のようなデフォルトの値に変更することができます。

フラグメント置換の間に設定変更(回転など)が発生した場合、戻るアクションはアニメートされません。これは 文書化されたバグ まだサポートライブラリのrev 20に存在します。

230
dmanargias

アニメーションファイルを作成するのではなく、これを使用することを強くお勧めします。それがはるかに優れた解決策であるためです。 Android Studioはすでにデフォルトanimationを提供しています。新しいXMLファイルを作成しなくても使用できます。アニメーションの名前はAndroid.R.anim.slide_in_leftおよびAndroid.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();

出力:

enter image description here

18
Gowthaman M

私の修正した サポートライブラリ フラグメント遷移のためにViewアニメーション(つまり<translate>, <rotate>)とObject Animator(すなわち<objectAnimator>)の両方を使うことをサポートします。 NineOldAndroids で実装されています。詳細はgithubの私の文書を参照してください。

5
mark.kedzierski

私に関しては、私は視野方向が必要です:

で - >右からスワイプ

アウト - >左にスワイプ

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

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()
            }
        }
    }
}
1
Serg Burlaka

私はこれを解決します

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
1