Анимировать переход между фрагментами
Я пытаюсь оживить переход между фрагментами. Я получил ответ от следующего
Android Фрагменты и анимация
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();
И мой R.anim.slide_in_left
<?xml version="1.0" encoding="utf-8"?>
<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>
Но когда я попробовал это, это показало
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): FATAL EXCEPTION: main
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): java.lang.RuntimeException: Unknown animator name: translate
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:129)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:126)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.createAnimatorFromXml(AnimatorInflater.java:93)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.animation.AnimatorInflater.loadAnimator(AnimatorInflater.java:72)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.loadAnimator(FragmentManager.java:621)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:733)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:919)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.BackStackRecord.run(BackStackRecord.java:578)
02-08 16:27:37.961: ERROR/AndroidRuntime(1717): at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1217)
Есть идеи? Когда я проверял ссылку на Honeycomb API translate
есть. Что я упустил?
Есть ли другой способ оживить переход между фрагментами? Спасибо
9 ответов
Вам нужно использовать новый android.animation
рамки (объектные аниматоры) с FragmentTransaction.setCustomAnimations
так же как FragmentTransaction.setTransition
,
Вот пример использования setCustomAnimations
из FragmentHideShow.java ApiDemos:
ft.setCustomAnimations(android.R.animator.fade_in, android.R.animator.fade_out);
и вот соответствующий аниматор XML из res / animator / fade_in.xml:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:interpolator/accelerate_quad"
android:valueFrom="0"
android:valueTo="1"
android:propertyName="alpha"
android:duration="@android:integer/config_mediumAnimTime" />
Обратите внимание, что вы можете объединить несколько аниматоров, используя <set>
так же, как вы могли бы с более старой анимацией.
РЕДАКТИРОВАТЬ: Поскольку люди спрашивают о слайд-ин / слайд-аут, я прокомментирую это здесь.
Выдвижной и выдвижной
Вы можете, конечно, оживить translationX
, translationY
, x
, а также y
Свойства, но, как правило, слайды включают анимацию контента за пределы экрана. Насколько я знаю, нет никаких свойств перехода, которые используют относительные значения. Однако это не мешает вам писать их самостоятельно. Помните, что для анимации свойств просто требуются методы getter и setter для объектов, которые вы анимируете (в данном случае представлений), так что вы можете просто создать свой собственный getXFraction
а также setXFraction
методы на вашем подклассе представления, как это:
public class MyFrameLayout extends FrameLayout {
...
public float getXFraction() {
return getX() / getWidth(); // TODO: guard divide-by-zero
}
public void setXFraction(float xFraction) {
// TODO: cache width
final int width = getWidth();
setX((width > 0) ? (xFraction * width) : -9999);
}
...
}
Теперь вы можете анимировать свойство 'xFraction', например так:
res / animator / slide_in.xml:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:valueFrom="-1.0"
android:valueTo="0"
android:propertyName="xFraction"
android:duration="@android:integer/config_mediumAnimTime" />
Обратите внимание, что если объект, в котором вы анимируете, не такой же ширины, как его родительский объект, все будет выглядеть не совсем правильно, поэтому вам может потребоваться настроить реализацию свойства в соответствии с вашим вариантом использования.
Я сделал так:
Добавьте этот метод, чтобы заменить фрагменты анимацией:
public void replaceFragmentWithAnimation(android.support.v4.app.Fragment fragment, String tag){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
transaction.replace(R.id.fragment_container, fragment);
transaction.addToBackStack(tag);
transaction.commit();
}
Вы должны добавить четыре анимации в папку anim, которая связана с ресурсом:
enter_from_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="-100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
exit_to_right.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700" />
</set>
enter_from_right.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="100%" android:toXDelta="0%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700" />
</set>
exit_to_left.xml:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="false">
<translate
android:fromXDelta="0%" android:toXDelta="-100%"
android:fromYDelta="0%" android:toYDelta="0%"
android:duration="700"/>
</set>
Выход:
Готово
Если вы можете позволить себе привязать себя только к Lollipop и позже, это, кажется, делает свое дело:
import android.transition.Slide;
import android.util.Log;
import android.view.Gravity;
.
.
.
f = new MyFragment();
f.setEnterTransition(new Slide(Gravity.RIGHT));
f.setExitTransition(new Slide(Gravity.LEFT));
getFragmentManager()
.beginTransaction()
.replace(R.id.content, f, FRAG_TAG) // FRAG_TAG is the tag for your fragment
.commit();
Надеюсь это поможет.
Вот слайд-анимация между фрагментами:
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.animator.enter_anim, R.animator.exit_anim);
transaction.replace(R.id.listFragment, new YourFragment());
transaction.commit();
Мы используем объект Animator.
Вот два xml-файла в подпапке аниматора.
enter_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="x"
android:valueFrom="2000"
android:valueTo="0"
android:valueType="floatType" />
</set>
exit_anim.xml
<?xml version="1.0" encoding="utf-8"?>
<set>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:propertyName="x"
android:valueFrom="0"
android:valueTo="-2000"
android:valueType="floatType" />
</set>
Я надеюсь, что это поможет кому-то.
Для всех, кого поймают, убедитесь, что setCustomAnimations вызывается перед вызовом для замены / добавления при построении транзакции.
Попробуйте использовать это простое и быстрое решение. Android предоставляет некоторые настройки по умолчанию animation
s.
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();
Выход:
Реализация FragmentTransaction в Android SDK требует Animator
в то время как поддержка библиотеки хочет Animation
, не спрашивайте меня, почему, но после комментария странного лука я изучил код Android 4.0.3 и библиотеку поддержки.
Android SDK использует loadAnimator()
и поддержка использования библиотеки loadAnimation()
Чтобы добавить более современный ответ на этот старый вопрос, если вы перешли на Material Design, это можно легко сделать с помощью предоставленной библиотеки движений - подробнее на https://material.io/develop/android/ тематика / движение.