Я показываю, DialogFragment
когда пользователь нажимает строку в ListView
. Я бы хотел оживить показ диалога так, чтобы он увеличивался из центра строки. Подобный эффект можно увидеть при открытии папки из лаунчера.
Одна идея, которая у меня возникла, - это комбинация TranslateAnimation
и ScaleAnimation
. Есть другой способ?
android
android-fragments
android-animation
Эдвард Дейл
источник
источник
Ответы:
Будучи
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
рост от точного центра ряда.Удачи!
источник
setStyle(DialogFragment.STYLE_NORMAL, R.style.MyCustomTheme)
наonCreate(bundle)
См .: developer.android.com/reference/android/app/DialogFragment.htmlПроверьте этот код, он работает для меня
// Анимация скольжения вверх
<?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; }
источник
DialogFragment имеет общедоступный метод getTheme (), который вы можете игнорировать именно по этой причине. В этом решении используется меньше строк кода:
public class MyCustomDialogFragment extends DialogFragment{ ... @Override public int getTheme() { return R.style.MyThemeWithCustomAnimation; } }
источник
AppTheme.NoActionBar
то время как DialogFragment использует значение по умолчаниюAppTheme
. Вышеупомянутый метод решил мою проблему, имея согласованную тему как во фрагменте, так и в действии.Чтобы получить полноэкранный диалог с анимацией, напишите следующее ...
Стили:
<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()); }
источник
Используйте вид декора внутри onStart во фрагменте диалога
@Override public void onStart() { super.onStart(); final View decorView = getDialog() .getWindow() .getDecorView(); decorView.animate().translationY(-100) .setStartDelay(300) .setDuration(300) .start(); }
источник
В DialogFragment настраиваемая анимация вызывается onCreateDialog. DialogAnimation - это пользовательский стиль анимации в предыдущем ответе.
public Dialog onCreateDialog(Bundle savedInstanceState) { final Dialog dialog = super.onCreateDialog(savedInstanceState); dialog.getWindow().getAttributes().windowAnimations = R.style.DialogAnimation; return dialog; }
источник
Вы смотрели тренинг для разработчиков Android по изменению масштаба изображения ? Может быть хорошей отправной точкой.
Вы, вероятно, захотите создать собственный класс, расширяющийся,
DialogFragment
чтобы это работало.Кроме того, взгляните на Jake Whartons NineOldAndroids для совместимости с API-интерфейсом Honeycomb Animation вплоть до уровня API 1.
источник
Если вы хотите работать с API, вы должны делать это внутри DialogFragemnt-> onStart, а не внутри onCreateDialog
@Override public void onStart() { if (getDialog() == null) { return; } getDialog().getWindow().setWindowAnimations( R.style.DlgAnimation); super.onStart(); }
источник
Добавьте этот код в значения 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"/>
вызовите 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;
источник