Анимации Android objectAnimator ДЕЙСТВИТЕЛЬНО медленные

Сначала я думал, что моя анимация вообще не работает, потому что новая Fragment ViewGroup просто появлялась на экране в одном кадре. Затем я замедлил анимацию, чтобы она занимала 3 секунды (3000 миллисекунд), и обнаружил, что она происходит такими большими кусками, что все происходит в одном кадре. Когда я увеличил его до 3 секунд, он получил около 4 кадров в секунду, что довольно плохо. Я работаю с эмулятором Genymotion. В целом эмулятор кажется очень быстрым, например, когда я щелкаю приложение «Настройки».

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

Новая ViewGroup — это пользовательский класс SlideableLayout, который предоставляет следующее свойство:

public float getXFraction() {
    final int width = getWidth();
    if (width != 0) {
        return getX() / getWidth();
    } else {
        return getX();
    }
}

public void setXFraction(float xFraction) {
    Log.d("SL", "setting xFraction="+xFraction);
    final int width = getWidth();
    if (width > 0) {
        setX(xFraction * width);
    } else {
        setX(-10000);
    }
}

Затем я добавляю фрагмент следующим образом:

getFragmentManager()
    .beginTransaction()
    .setCustomAnimations(R.animator.slide_in_from_right, R.animator.slide_out_to_the_left,
            R.animator.slide_in_from_the_left, R.animator.slide_out_to_the_right)
    .add(R.id.navrootlayout, fragment)
    .addToBackStack(null)
    .commit();

Анимация R.animator.slide_in_from_right выглядит так:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:interpolator="@interpolator/decelerate_cubic"
        android:valueFrom="1"
        android:valueTo="0"
        android:valueType="floatType"
        android:propertyName="xFraction"
        android:duration="@integer/navigation_animation_duration"/>
</set>

Таким образом, система должна анимировать свойство xFraction от 1.0 до 0.0, и каждый кадр должен рассчитываться ОЧЕНЬ быстро, поскольку все, что она делает, это получает width и умножает на дробь.

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

РЕДАКТИРОВАТЬ:

Есть ли какие-то параметры конфигурации, которые мне нужно установить в моем эмуляторе Genymotion, чтобы анимация работала с нормальной частотой кадров?

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения


person Kenny Wyland    schedule 12.07.2016    source источник
comment
Какова продолжительность?   -  person JoxTraex    schedule 12.07.2016
comment
3000 миллисекунд (т.е. 3 секунды)   -  person Kenny Wyland    schedule 12.07.2016
comment
Это использование пользовательского тестового приложения для удаления вашего кода из уравнения анимации? Вы хотите изолировать его, чтобы определить, является ли это проблемой кода или проблемой анимации. Выделив код анимации в простой сценарий тестового приложения, вы можете изолировать эти условия.   -  person JoxTraex    schedule 12.07.2016
comment
В моем проекте нет другого реального кода, я просто запускаю новое приложение прямо сейчас. Это просто фрагмент с кнопкой, затем, когда вы нажимаете эту кнопку, он анимирует новый фрагмент на место. Это все, что приложение делает на данный момент. Разобрать его дальше будет очень сложно.   -  person Kenny Wyland    schedule 12.07.2016


Ответы (1)


По-видимому, это вызвано xFraction и yFraction, которые должны быть реализованы корневыми представлениями обоих фрагментов: https://stackoverflow.com/ а/25701362/2964379

Честно говоря, это просто эпический фейл. Ожидает ли Google, что люди будут расширять каждое отдельное представление только для того, чтобы добавить эти два метода?

Простое, но ужасное решение состоит в том, чтобы установить для свойства значение x или y и установить значения на большое число, равное или превышающее экран, тогда оно будет работать быстро, но в зависимости от значения в анимации могут быть огромные пробелы.

Лучшее решение (от https://stackoverflow.com/a/20480676/2964379) - установить для ваших аниматоров значение x или y, но полностью удалите valueFrom и valueTo. Затем переопределите onCreateAnimator всех фрагментов (в пользовательском базовом классе фрагментов), используйте AnimatorInflater.loadAnimator(activity, nextAnim), чтобы получить набор аниматоров, и вызовите setFloatValues для его дочерних элементов. Например, вы можете проверить nextAnim == R.animator.slide_in_from_right и позвонить setFloatValues(screenWidth, 0). Работает отлично!

person 0101100101    schedule 14.06.2017