Анимация двухслойных рисуемых элементов

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

<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
             android:drawable="@drawable/abs__spinner_48_outer_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="0"
             android:toDegrees="1080" />
    </item>
    <item>
        <rotate
             android:drawable="@drawable/abs__spinner_48_inner_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="720"
             android:toDegrees="0" />
    </item>
</layer-list>

Является ли это просто ограничением этих платформ или есть альтернативный синтаксис, который я могу использовать (либо вообще, либо специально предназначенный для pre-API11) для достижения желаемой функциональности?


person Jake Wharton    schedule 31.12.2011    source источник


Ответы (2)


Ограничение платформы действительно существует, хотя это не то, что вы могли подумать. Проблема в том, что до API11 в RotateDrawable был некоторый грубый код, требующий, чтобы анимация вращалась по часовой стрелке, проверяя, больше ли toDegrees, чем fromDegrees; в противном случае они были вынуждены равняться друг другу. Если вы изменили свой пример, чтобы второй элемент перемещался в прямом направлении (от 0 до 720 или даже от -720 до 0), оба изображения будут нормально анимироваться на всех платформах; хотя я понимаю, что это противоречит цели того, к чему вы стремитесь.

Взгляните на кешированную версию Google Codesearch RotateDrawable.inflate(), которая представляет собой версию 2.3 метода, используемого для преобразования XML в объект, и вы поймете, что я имею в виду.

RotateDrawable.java ... код нарушения находится вокруг строки 235...

    float fromDegrees = a.getFloat(
            com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f);
    float toDegrees = a.getFloat(
            com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f);

    toDegrees = Math.max(fromDegrees, toDegrees); //<--There's the culprit

Это берет блок XML, такой как второй элемент, который у вас есть, и превращает его в RotateDrawable, который заканчивается тем же значением для fromDegrees и toDegrees (в вашем случае 720), в результате чего изображение просто останавливается. Вы можете визуально проверить это, установив начальное значение на некоторое значение, не кратное 360 (например, 765). Вы увидите, что изображение по-прежнему не анимируется, а поворачивается к исходной координате.

Эта неудобная проверка была удалена в исходных кодах Honeycomb/ICS, поэтому на этих платформах вы можете выполнять обратное вращение. Кроме того, не похоже, что есть способ установить эти значения из кода Java, поэтому в будущем может появиться пользовательский RotateDrawableCompat :)

ХТН

person devunwired    schedule 02.01.2012
comment
Обновленная справочная ссылка: github.com/android/platform_frameworks_base/blob/ - person Jake Wharton; 18.03.2012

Похоже, что быстрое и грязное решение, чтобы заставить это работать в предварительном сотовом соте, состоит в том, чтобы просто перевернуть от и до во втором повороте. Это не идеально, но, по крайней мере, эта штука крутится (даже если это немного более «скучно»). Вот как ABS, похоже, решил эту проблему.

  <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <rotate
             android:drawable="@drawable/abs__spinner_48_outer_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="0"
             android:toDegrees="1080" />
    </item>
    <item>
        <rotate
             android:drawable="@drawable/abs__spinner_48_inner_holo"
             android:pivotX="50%"
             android:pivotY="50%"
             android:fromDegrees="0"
             android:toDegrees="720" /> <!-- Like this -->
    </item>
  </layer-list>
person dmon    schedule 22.11.2013