it-swarm.com.ru

Android Фрагменты и анимация

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

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

256
alexanderblom

Для анимации перехода между фрагментами или для анимации процесса отображения или скрытия фрагмента вы используете 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>
373
Reto Meier

Если вам не нужно использовать библиотеку поддержки, посмотрите Roman's answer.

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

После просмотра ответов Рето и слепых я получил следующий код.

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

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-й версии библиотеки поддержки.

230
dmanargias

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

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

18
Gowthaman M

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

5
mark.kedzierski

Что касается меня, мне нужно посмотреть направление:

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

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

Вот у меня работает код:

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

Я решаю это так, как показано ниже

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