Фрагменты Android и анимация - PullRequest
256 голосов
/ 27 января 2011

Как вы должны реализовать тот тип скольжения, который используется, например, клиентом Honeycomb Gmail?

Может ли TransactionManager обрабатывать это автоматически, добавляя и удаляя фрагменты, это сложно проверить из-заэмулятор слайд-шоу:)

Ответы [ 6 ]

374 голосов
/ 27 января 2011

Для анимации перехода между фрагментами или для анимации процесса показа или сокрытия фрагмента вы используете Fragment Manager, чтобы создать Fragment Transaction.

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

В следующем коде показано, как заменить фрагмент, выдвинув один фрагмент и сдвинув другой на его место.

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

Чтобы добиться того же, скрыв или отобразив фрагментВы просто позвоните ft.show или ft.hide, передавая фрагмент, который вы хотите отобразить или скрыть соответственно.

Для справки, определения анимации XML будут использовать тег objectAnimator.Пример slide_in_left может выглядеть примерно так:

<?xml version="1.0" encoding="utf-8"?>
<set>
  <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:propertyName="x" 
    android:valueType="floatType"
    android:valueFrom="-1280"
    android:valueTo="0" 
    android:duration="500"/>
</set>
231 голосов
/ 05 июля 2013

Если вам не нужно использовать библиотеку поддержки, взгляните на ответ Романа .

Но если вы хотите использовать библиотеку поддержки , вам придется использовать старую инфраструктуру анимации, как описано ниже.

После консультации с ответами и жалюзи Рето я получил следующий код:

Фрагменты появляются , скользящие справа и , скользящие влево при нажатии назад.

FragmentManager fragmentManager = getSupportFragmentManager();

FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit);

CustomFragment newCustomFragment = CustomFragment.newInstance();
transaction.replace(R.id.fragment_container, newCustomFragment );
transaction.addToBackStack(null);
transaction.commit();

Порядок важен. Это означает, что вы должны позвонить setCustomAnimations() до replace(), иначе анимация не вступит в силу!

Затем эти файлы должны быть помещены в папку res / anim .

enter.xml

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

exit.xml

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="0"
               android:toXDelta="-100%"
               android:interpolator="@android:anim/accelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_enter.xml

<set>
    <translate xmlns:android="http://schemas.android.com/apk/res/android"
               android:fromXDelta="-100%"
               android:toXDelta="0"
               android:interpolator="@android:anim/decelerate_interpolator"
               android:duration="@android:integer/config_mediumAnimTime"/>
</set>

pop_exit.xml

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

Длительность анимации может быть изменена на любое из значений по умолчанию, например @android:integer/config_shortAnimTime или любое другое число.

Обратите внимание, что если между заменами фрагментов происходит изменение конфигурации (например, вращение), обратное действие не анимируется. Это задокументированная ошибка , которая все еще существует в 20-й версии библиотеки поддержки.

18 голосов
/ 22 сентября 2017

Я настоятельно рекомендую вам использовать это вместо создания файла анимации, потому что это гораздо лучшее решение. Android Studio уже предоставляет по умолчанию animation, которую можно использовать без создания какого-либо нового файла XML. Названия анимаций: android.R.anim.slide_in_left и android.R.anim.slide_out_right , и вы можете использовать их следующим образом:

фрагментTransaction.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

5 голосов
/ 20 марта 2014

Моя измененная библиотека поддержки поддерживает использование как анимаций просмотра (т.е. <translate>, <rotate>), так и аниматоров объектов (например, <objectAnimator>) для переходов фрагментов.Это реализовано с NineOldAndroids .За подробностями обращайтесь к моей документации по github.

1 голос
/ 19 марта 2019

Что касается меня, мне нужно посмотреть дирекцию:

in -> проведите вправо

out -> проведите влево

Здесь у меня работает код:

slide_in_right.xml

<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>

slide_out_left.xml

 <set xmlns:android="http://schemas.android.com/apk/res/android">
        <translate android:fromXDelta="0" android:toXDelta="-50%p"
                android:duration="@android:integer/config_mediumAnimTime"/>
        <alpha android:fromAlpha="1.0" android:toAlpha="0.0"
                android:duration="@android:integer/config_mediumAnimTime" />
    </set>

код транзакции:

inline fun FragmentActivity.setContentFragment(
        containerViewId: Int,
        backStack: Boolean = false,
        isAnimate: Boolean = false,
        f: () -> Fragment

): Fragment? {
    val manager = supportFragmentManager
    return f().apply {
        manager.beginTransaction().let {
            if (isAnimate)
                it.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left)

            if (backStack) {
                it.replace(containerViewId, this, "Fr").addToBackStack("Fr").commit()
            } else {
                it.replace(containerViewId, this, "Fr").commit()
            }
        }
    }
}
1 голос
/ 25 февраля 2015

Я решаю этот путь ниже

Animation anim = AnimationUtils.loadAnimation(this, R.anim.slide);
fg.startAnimation(anim);
this.fg.setVisibility(View.VISIBLE); //fg is a View object indicate fragment
...