ポイントから成長するアニメーションでDialogFragmentを表示する


93

私はAを示していますDialogFragmentユーザーが行をタップしたときListView。行の中央から成長するようにダイアログの表示をアニメーション化したいと思います。ランチャーからフォルダーを開くと、同様の効果が見られます。

私が持っていたひとつのアイデアは、の組み合わせですTranslateAnimationScaleAnimation。別の方法はありますか?


1
DialogFragmentのアニメーションについては、リンクを参照してください。
ASH

回答:


168

ビーイングDialogFragmentのためのラッパーDialogクラス、あなたはあなたのベースにテーマを設定する必要がありDialog、あなたがしたいアニメーションを取得するには:

public class CustomDialogFragment extends DialogFragment implements OnEditorActionListener
{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    {
        return super.onCreateView(inflater, container, savedInstanceState);
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 
    {
        // Set a theme on the dialog builder constructor!
        AlertDialog.Builder builder = 
            new AlertDialog.Builder( getActivity(), R.style.MyCustomTheme );

        builder  
        .setTitle( "Your title" )
        .setMessage( "Your message" )
        .setPositiveButton( "OK" , new DialogInterface.OnClickListener() 
            {      
              @Override
              public void onClick(DialogInterface dialog, int which) {
              dismiss();                  
            }
        });
        return builder.create();
    }
}

次に、必要なアニメーションを含めるテーマを定義するだけです。styles.xmlカスタムテーマを追加します。

<style name="MyCustomTheme" parent="@android:style/Theme.Panel">
    <item name="android:windowAnimationStyle">@style/MyAnimation.Window</item>
</style>

<style name="MyAnimation.Window" parent="@android:style/Animation.Activity"> 
    <item name="android:windowEnterAnimation">@anim/anim_in</item>
    <item name="android:windowExitAnimation">@anim/anim_out</item>
</style>    

次に、アニメーションファイルをres / animフォルダーに追加します。

android:pivotYが鍵です)

anim_in.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="0.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:fillAfter="false"
        android:startOffset="200"
        android:duration="200" 
        android:pivotX = "50%"
        android:pivotY = "-90%"
    />
    <translate
        android:fromYDelta="50%"
        android:toYDelta="0"
        android:startOffset="200"
        android:duration="200"
    />
</set>

anim_out.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="1.0"
        android:toXScale="0.0"
        android:fromYScale="1.0"
        android:toYScale="0.0"
        android:fillAfter="false"
        android:duration="200" 
        android:pivotX = "50%"        
        android:pivotY = "-90%"        
    />
    <translate
        android:fromYDelta="0"
        android:toYDelta="50%"
        android:duration="200"
    />
</set>

最後に、ここでトリッキーなことは、アニメーションを各行の中央から大きくすることです。行が画面を水平方向に埋めているので、一方でandroid:pivotX値は静的になります。一方、android:pivotY値をプログラムで変更することはできません。

私が提案しているのは、android:pivotY属性のパーセンテージ値がそれぞれ異なる複数のアニメーション(およびそれらのアニメーションを参照する複数のテーマ)を定義することです。次に、ユーザーが行をタップしたときに、画面上の行のパーセントでY位置を計算します。位置をパーセンテージで把握し、適切なandroid:pivotY値を持つテーマをダイアログに割り当てます。

それは完璧な解決策ではありませんが、あなたのためのトリックを行うことができます。結果が気に入らない場合は、行の正確な中心からのDialogFragment単純なView成長を忘れてアニメーション化することをお勧めします。

幸運を!


画面上のさまざまな場所に複数のアニメーションを配置することをお勧めします。それはハックですが、それが唯一の方法のようです。
Edward Dale

これは> API 11でのみ機能します@Kiran Babuの回答は回避策です
Blundell

これらのアニメーションが完了したときにコールバックを取得する方法があるかどうか知っていますか?2つの部分からなるアニメーションを実行します。1つはダイアログがスライドインし、次にビューがフェードインします。リスナーをwindowAnimationsにアタッチするにはどうすればよいですか?
android_student 2015

素晴らしい!探していたのはまさしく!
Aleksey Timoshchenko 2016年

2
テーマの設定はsetStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)onCreate(bundle)See:developer.android.com/reference/android/app/DialogFragment.html
tropicalfish

117

このコードを確認してください、私にとってはうまくいきます

//上にスライドするアニメーション

<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="100%"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toXDelta="0" />

</set>

//スライドアニメーション

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >

    <translate
        android:duration="@android:integer/config_mediumAnimTime"
        android:fromYDelta="0%p"
        android:interpolator="@android:anim/accelerate_interpolator"
        android:toYDelta="100%p" />

</set>

// スタイル

<style name="DialogAnimation">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

//ダイアログフラグメントの内側

@Override
public void onActivityCreated(Bundle arg0) {
    super.onActivityCreated(arg0);
    getDialog().getWindow()
    .getAttributes().windowAnimations = R.style.DialogAnimation;
}

8
申し訳ありませんが、これは私の質問にまったく答えません。
エドワードデール

3
これは、OPが求めているものとは厳密には一致しないかもしれませんが、良いエントリーポイントだと思います。
mdelolmo 2013

2
素晴らしい例!私のために働いた唯一のサンプル。トリックは、onActivityCreated(...)メソッドでアニメーション/テーマを設定することです
tomurka '

3
これは便利かもしれませんが、質問にはまったく答えません。
Olayinka 2014

これらのアニメーションが完了したときにコールバックを取得する方法があるかどうか知っていますか?2つの部分からなるアニメーションを実行します。1つはダイアログがスライドインし、次にビューがフェードインします。リスナーをwindowAnimationsにアタッチするにはどうすればよいですか?
android_student 2015

22

DialogFragmentにはpublic getTheme()メソッドがあり、この正確な理由で乗り越えることができます。このソリューションでは、使用するコード行が少なくなります。

public class MyCustomDialogFragment extends DialogFragment{
    ...
    @Override
    public int getTheme() {
        return R.style.MyThemeWithCustomAnimation;
    }
}

1
心配はいりません...シンプルでストレートなソリューション。
Noundla Sandeep 2016

これが私にとって最良の答えです!
スーパーユーザー、

元の質問とは関係ありませんが、MainAcitvityに表示されているギャラリーで、ユーザーがクリックするとDialogFragmentのスライドショーがアクティブになります。ただし、スライドショーから戻るたびに、MainActivityにジャークがあります。これはAppTheme.NoActionBar、DialogFragmentがデフォルトを使用しているときにMainActivityを使用しているためですAppTheme。上記の方法は、フラグメントとアクティビティの両方に一貫したテーマを持たせることで私の問題を解決しました。
tingyik90

ブロ、あなたは天才です
ジャッキー・チョン

この解決策は私にとってうまくいきました。しかし、一つのことが私を混乱させました。テーマでwindowEnterAnimationまたはwindowExitAnimationを直接設定しても、DialogFragmentsアニメーションに違いはありません。私にとってうまくいったことは、windowAnimationStyleを、スタイルを定義した個別のXMLファイルに設定し、そこに開始および終了アニメーションを設定すること
でした

9

アニメーション付きのフルスクリーンダイアログを取得するには、次のように記述します...

スタイル:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="actionModeBackground">?attr/colorPrimary</item>
    <item name="windowActionModeOverlay">true</item>
</style>

<style name="AppTheme.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.NoActionBar.FullScreenDialog">
    <item name="android:windowAnimationStyle">@style/Animation.WindowSlideUpDown</item>
</style>

<style name="Animation.WindowSlideUpDown" parent="@android:style/Animation.Activity">
    <item name="android:windowEnterAnimation">@anim/slide_up</item>
    <item name="android:windowExitAnimation">@anim/slide_down</item>
</style>

res / anim / slide_up.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="100%"
        android:toYDelta="0%"/>
</set>

res / anim / slide_down.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
     android:shareInterpolator="@android:interpolator/accelerate_quad">

    <translate
        android:duration="@android:integer/config_shortAnimTime"
        android:fromYDelta="0%"
        android:toYDelta="100%"/>
</set>

Javaコード:

public class MyDialog extends DialogFragment {

    @Override
    public int getTheme() {
        return R.style.AppTheme_NoActionBar_FullScreenDialog;
    }
}

private void showDialog() {
    FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
    Fragment previous = getSupportFragmentManager().findFragmentByTag(MyDialog.class.getName());
    if (previous != null) {
        fragmentTransaction.remove(previous);
    }
    fragmentTransaction.addToBackStack(null);

    MyDialog dialog = new MyDialog();
    dialog.show(fragmentTransaction, MyDialog.class.getName());
}

4

ダイアログフラグメントのonStart内で装飾ビューを使用する

@Override
public void onStart() {
    super.onStart();


    final View decorView = getDialog()
            .getWindow()
            .getDecorView();

    decorView.animate().translationY(-100)
            .setStartDelay(300)
            .setDuration(300)
            .start();

}

1
基になるビューは後でクリックできないようです
HaydenKai

3

DialogFragmentでは、カスタムアニメーションはonCreateDialogと呼ばれます。「DialogAnimation」は、以前の回答のカスタムアニメーションスタイルです。

public Dialog onCreateDialog(Bundle savedInstanceState) 
{
    final Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation;
    return dialog;
}

1

ビューのズームに関するAndroidデベロッパートレーニングをご覧になりましたか?良い出発点になるかもしれません。

DialogFragmentこれを機能させるために拡張するカスタムクラスを作成する必要があります。

また、Honeycomb Animation APIの互換性について、Jake Whartons NineOldAndroidsを調べて、APIレベル1に戻ってください。


1

APIで作業する場合は、onCreateDialog内ではなく、DialogFragemnt-> onStart内で行う必要があります。

@Override
    public void onStart() 
    {
        if (getDialog() == null) 
        {
            return;
        }

        getDialog().getWindow().setWindowAnimations(
                  R.style.DlgAnimation);

        super.onStart();
    }

私の意見では最良の解決策です。AlertDialogsでも機能します。onShowListenerで使用するだけです。ありがとう!
Gabor Novak

0

値アニメーションにこのコードを追加します

 <scale
    android:duration="@android:integer/config_longAnimTime"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:toXScale="1.0"
    android:toYScale="1.0"
    android:pivotX="50%"
    android:pivotY="50%"/>
<alpha
    android:fromAlpha="0.1"
    android:toAlpha="1.0"
    android:duration="@android:integer/config_longAnimTime"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>

styles.xmlを呼び出す

<style name="DialogScale">
    <item name="android:windowEnterAnimation">@anim/scale_in</item>
    <item name="android:windowExitAnimation">@anim/scale_out</item>
</style>

Javaコード:Onclickを設定

public void onClick(View v) {
        fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView());
      //  Dialogs.fab_onclick(R.style.DialogScale, "Scale");

    }

メソッドの設定:

alertDialog.getWindow().getAttributes().windowAnimations = type;
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.