Android - пользовательская анимация при транзакции фрагмента не выполняется


83

Я использую Google API 8 (Android 2.2) с пакетом поддержки v4.

Никаких ошибок или анимации не выдает.

Сделка:

FragmentTransaction transaction = manager.beginTransaction();       
transaction.replace(R.id.content, myFragment);
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.commit();

Анимации:

slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <translate
        android:duration="700"
        android:fromXDelta="-100%"
        android:toXDelta="0%" >
    </translate>
</set>

slide_out_right.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="700"
        android:fromXDelta="0%"
        android:toXDelta="100%" >
    </translate>
</set>

Кто-нибудь знает, что здесь происходит?


1
Фрагменты не были представлены до Honeycomb (API 11, Android 3.0). Это могло быть проблемой, но я думал, что Eclipse вам скажет.
Стив Блэквелл,

6
Вот почему я использую пакет поддержки.
adheus

Ответы:


257

Менеджер складывал мою транзакцию до того, как я установил анимацию, поэтому он складывает транзакцию без анимации (грустно, но это правда), и это происходит, даже если я фиксирую транзакцию после setCustomAnimations().

Решение состоит в том, чтобы сначала установить анимацию:

FragmentTransaction transaction = manager.beginTransaction();       
transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
transaction.replace(R.id.content, myFragment);
transaction.commit();

поэтому вам нужно разделить оператор, чтобы избежать трюка с самовозвратом объекта
sherpya 08

4
transaction.something().somethingelse().replace().commit(), многие методы Android возвращаются, thisпоэтому вы можете избежать повторного ввода переменной, но каким-то образом здесь проявляется побочный эффект, и его setCustomAnimations()следует вызывать отдельно
sherpya

46
Отметим, что «трюк с самовозвратом объекта» называется «цепочкой методов»
Егор

Метод цепочки вышеуказанного вызова определенно работает. Просто протестировал в собственном проекте.
MawrCoffeePls

Для дополнительного, чтобы анимировать фрагмент при извлечении из заднего стека, используйте transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right, R.anim.slide_in_left, R.anim.slide_out_right);вместо этого.
Джастин

24

Как было предложено выше, отдельные утверждения определенно будут работать. Но уловка здесь в том, чтобы setCustomAnimationперед установкой типа транзакции, а именно. add, replaceи т. д. иначе это не так. Таким образом, применение той же логики method chainingтоже работает. например.

getSupportFragmentManager()
        .beginTransaction()
        .setCustomAnimations(R.anim.a_slide_up,
                             R.anim.a_slide_down,
                             R.anim.a_slide_up,
                             R.anim.a_slide_down)
        .add(R.id.root_layout, 
             MyFrag.newInstance())
        .addToBackStack("MyFrag")
        .commit();

Поместите его сюда, чтобы тот, кто предпочитает, method chainingнашел его полезным. Ура!


1
Меня слегка обидело то, как вы используете оператор «точка» для цепочки методов.
Shaishav

1
Согласен @Shaishav, написал этот ответ два года назад, обновил его .. Спасибо!
Harisewak

7

Оставить это здесь, поскольку это самый популярный вопрос. У меня была такая же проблема с транзакцией фрагмента, которая не анимируется. Причина заключалась в том, что атрибут был android:animateLayoutChangesустановлен trueв содержащем макете.

Я надеюсь, что это поможет кому-то сэкономить время на поиске решения, так как это может быть трудно заметить при наличии вложенных макетов в разных файлах.


Анимация сейчас работает, но новая проблема - изменено поведение анимации. прежде, чем он скользит по горизонтали (как и ожидалось). теперь расширяется из угла
Шарад Кале

0

Другой причиной может быть ненужное размещение fragmentTransaction.show()перед фиксацией. Из-за этого всплывающие переходы не отображаются в некоторых версиях API Android.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.