Анимация перехода между фрагментами



Я пытаюсь оживить переход между фрагментами. Я получил ответ от следующего
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();


и мой Р. аним.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 reference translate - это есть. Что я пропустил?

Есть ли другой способ оживить переход между фрагментами?
Спасибо

573   8  

8 ответов:

вы должны использовать новый android.animation рамки (аниматоры объектов) с FragmentTransaction.setCustomAnimations а также FragmentTransaction.setTransition.

пример использования setCustomAnimations из ApiDemos' FragmentHideShow.java:

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>, просто как вы могли бы с более старой анимации рамки.


EDIT: поскольку люди спрашивают о слайд-в / слайд-из, я прокомментирую это здесь.

Slide-in и slide-out

вы можете, конечно, оживить 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();
}

вы должны добавитьчетыре анимации на аним

Нурикответ был очень полезным, но я не мог заставить его работать, пока не нашел этой. Короче говоря, если вы используете библиотеку совместимости (например, SupportFragmentManager вместо FragmentManager), синтаксис файлов анимации XML будет отличаться.

Если вы можете позволить себе привязать себя только к леденцу и позже, это, кажется, делает трюк:

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();

мы используем objectAnimator.

вот два 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 SDK реализация FragmentTransaction хочет Animator в то время как библиотека поддержки хочет Animation, Не спрашивайте меня, почему, но после комментария strangeluk я заглянул в код android 4.0.3 и библиотеку поддержки. Android SDK использует loadAnimator() и библиотека поддержки использует loadAnimation()

попробуйте использовать это простое и голодное решение. 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();

выход:

enter image description here

Comments

    Ничего не найдено.