Подтвердить что ты не робот

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

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

4b9b3361

Ответ 1

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

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

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

НТН

Ответ 2

Кажется, что быстрое и грязное решение, чтобы заставить эту рабочую среду использовать в сотах, - это просто перевернуть из и во втором вращении. Это не идеально, но по крайней мере вещь вращается вокруг (даже если это немного более "скучно" ). Именно так АБС, похоже, решила это.

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