Saya menunjukkan DialogFragment
saat pengguna mengetuk baris dalam ListView
. Saya ingin menganimasikan tampilan dialog sehingga dialog itu tumbuh dari tengah baris. Efek serupa dapat dilihat saat membuka folder dari peluncur.
Satu gagasan yang saya miliki adalah kombinasi dari TranslateAnimation
dan ScaleAnimation
. Apakah ada cara lain?
android
android-fragments
android-animation
Edward Dale
sumber
sumber
Jawaban:
Sebagai
DialogFragment
pembungkusDialog
kelas, Anda harus menetapkan tema ke basis AndaDialog
untuk mendapatkan animasi yang Anda inginkan: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(); } }
Kemudian Anda hanya perlu menentukan tema yang akan menyertakan animasi yang Anda inginkan. Di styles.xml tambahkan tema khusus Anda:
<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>
Sekarang tambahkan file animasi di folder res / anim :
(
android:pivotY
adalah kuncinya)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>
Terakhir, hal yang sulit di sini adalah membuat animasi Anda tumbuh dari tengah setiap baris. Saya kira baris tersebut mengisi layar secara horizontal jadi, di satu sisi
android:pivotX
nilainya akan statis. Di sisi lain, Anda tidak dapat mengubahandroid:pivotY
nilai secara terprogram.Yang saya sarankan adalah, Anda menentukan beberapa animasi yang masing-masing memiliki nilai persentase yang berbeda pada
android:pivotY
atribut (dan beberapa tema yang mereferensikan animasi tersebut). Kemudian, saat pengguna mengetuk baris, hitung posisi Y dalam persentase baris di layar. Mengetahui posisi dalam persentase, tetapkan tema ke dialog Anda yang memiliki nilai yang sesuaiandroid:pivotY
.Ini bukan solusi yang tepat tetapi bisa melakukan trik untuk Anda. Jika Anda tidak menyukai hasilnya, maka saya sarankan untuk melupakan
DialogFragment
dan menganimasikanView
pertumbuhan sederhana dari tengah baris yang tepat.Semoga berhasil!
sumber
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)
dionCreate(bundle)
Lihat: developer.android.com/reference/android/app/DialogFragment.htmlLihat kode ini, ini berfungsi untuk saya
// Animasi geser ke atas
<?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>
// Animasi dowm geser
<?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>
// Gaya
<style name="DialogAnimation"> <item name="android:windowEnterAnimation">@anim/slide_up</item> <item name="android:windowExitAnimation">@anim/slide_down</item> </style>
// Di Dalam Fragmen Dialog
@Override public void onActivityCreated(Bundle arg0) { super.onActivityCreated(arg0); getDialog().getWindow() .getAttributes().windowAnimations = R.style.DialogAnimation; }
sumber
DialogFragment memiliki metode getTheme () publik yang dapat Anda kendalikan karena alasan yang tepat ini. Solusi ini menggunakan lebih sedikit baris kode:
public class MyCustomDialogFragment extends DialogFragment{ ... @Override public int getTheme() { return R.style.MyThemeWithCustomAnimation; } }
sumber
AppTheme.NoActionBar
saat DialogFragment menggunakan defaultAppTheme
. Metode di atas memecahkan masalah saya dengan memiliki tema yang konsisten baik dalam fragmen maupun aktivitas.Untuk mendapatkan dialog layar penuh dengan animasi, tulis yang berikut ini ...
Gaya:
<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>
Kode 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()); }
sumber
Gunakan tampilan dekorasi di dalam onStart di fragmen dialog Anda
@Override public void onStart() { super.onStart(); final View decorView = getDialog() .getWindow() .getDecorView(); decorView.animate().translationY(-100) .setStartDelay(300) .setDuration(300) .start(); }
sumber
Di DialogFragment, animasi kustom disebut onCreateDialog. 'DialogAnimation' adalah gaya animasi kustom di jawaban sebelumnya.
public Dialog onCreateDialog(Bundle savedInstanceState) { final Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; return dialog; }
sumber
Pernahkah Anda melihat Pelatihan Pengembang Android tentang Memperbesar Tampilan ? Mungkin titik awal yang bagus.
Anda mungkin ingin membuat kelas kustom yang diperluas
DialogFragment
agar ini berfungsi.Selain itu, lihat kompatibilitas Jake Whartons NineOldAndroids for Honeycomb Animation API hingga API Level 1.
sumber
Jika Anda ingin mengerjakan API, Anda harus melakukannya di dalam DialogFragemnt-> onStart dan bukan di dalam onCreateDialog
@Override public void onStart() { if (getDialog() == null) { return; } getDialog().getWindow().setWindowAnimations( R.style.DlgAnimation); super.onStart(); }
sumber
Tambahkan kode ini pada nilai anim
<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"/>
panggil di styles.xml
<style name="DialogScale"> <item name="android:windowEnterAnimation">@anim/scale_in</item> <item name="android:windowExitAnimation">@anim/scale_out</item> </style>
Pada kode java: setel Onclick
public void onClick(View v) { fab_onclick(R.style.DialogScale, "Scale" ,(Activity) context,getWindow().getDecorView().getRootView()); // Dialogs.fab_onclick(R.style.DialogScale, "Scale"); }
pengaturan pada metode:
alertDialog.getWindow().getAttributes().windowAnimations = type;
sumber