Анимированные двухслойные прорисовываемые элементы предварительно соты - PullRequest
14 голосов
/ 31 декабря 2011

Я пытаюсь анимировать два слоя рисунка для достижения эффекта индикатора неопределенности после соты.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>

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

Ответы [ 2 ]

11 голосов
/ 02 января 2012

Платформа действительно ограничена, хотя это не то, что вы могли бы подумать. Проблема заключается в том, что в pre-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 может быть в вашем будущем:)

НТН

1 голос
/ 22 ноября 2013

Похоже, что быстрое и грязное решение для того, чтобы заставить это работать в предварительной соте, это просто перевернуть от и до во втором повороте.Это не идеально, но, по крайней мере, вещь вращается (даже если это немного "скучно").Вот как 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>
...