1. ホーム
  2. android

FragmentTransactionのアニメーションが上からスライドしてくること

2023-09-07 04:20:32

質問

FragmentTransaction.setCustomAnimationsを使用して、以下のような効果を得ようとしています。

  1. フラグメントAを表示
  2. フラグメントAをフラグメントBに置き換えます。置き換え中もフラグメントAは表示されたままです。 フラグメント B は右からスライドしてくるはずです。フラグメント B は、フラグメント A の上をスライドするようにします。

スライドインアニメーションを設定するのは問題ありません。私の問題は、スライド イン アニメーションが実行されている間、フラグメント A をその位置にとどめ、フラグメント B の下にあるようにする方法がわからないことです。何をやっても、フラグメント A が上にあるように見えます。

どうすればこれを実現できますか?

以下はFragmentTransactionのコードです。

FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.nothing, R.anim.nothing,
    R.anim.slide_out_right);
ft.replace(R.id.fragment_content, fragment, name);
ft.addToBackStack(name);
ft.commit();

ご覧の通り、私はアニメーション R.anim.nothing を "out" のために定義しました。なぜなら、実際にはフラグメント A がトランザクションの間、ただそこに留まっている以外に何もして欲しくないからです。

アニメーションのリソースです。

スライド_イン_ライト.xml

<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime"
    android:fromXDelta="100%p"
    android:toXDelta="0"
    android:zAdjustment="top" />

nothing.xml

<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="@android:integer/config_mediumAnimTime"
    android:fromAlpha="1.0"
    android:toAlpha="1.0"
    android:zAdjustment="bottom" />

どのように解決するのですか?

私は、自分にとって有効な解決策を見つけました。私は、FragmentStatePagerAdapterを持つViewPagerを使用することにしました。ViewPagerはスワイプの動作を提供し、FragmentStatePagerAdapterはフラグメントをスワップします。あるページが、入ってくるページの下に表示される効果を得るための最後のトリックは、PageTransformer を使用することです。PageTransformer は ViewPager のデフォルトのページ間遷移をオーバーライドします。以下は、左側のページで翻訳と少量のスケーリングで効果を得るPageTransformerの例です。

public class ScalePageTransformer implements PageTransformer {
    private static final float SCALE_FACTOR = 0.95f;

    private final ViewPager mViewPager;

    public ScalePageTransformer(ViewPager viewPager) {
            this.mViewPager = viewPager;
    }

    @SuppressLint("NewApi")
    @Override
    public void transformPage(View page, float position) {
        if (position <= 0) {
            // apply zoom effect and offset translation only for pages to
            // the left
            final float transformValue = Math.abs(Math.abs(position) - 1) * (1.0f - SCALE_FACTOR) + SCALE_FACTOR;
            int pageWidth = mViewPager.getWidth();
            final float translateValue = position * -pageWidth;
            page.setScaleX(transformValue);
            page.setScaleY(transformValue);
            if (translateValue > -pageWidth) {
                page.setTranslationX(translateValue);
            } else {
                page.setTranslationX(0);
            }
        }
    }

}