Да! Ключ (недокументированный), который я обнаружил, читая код ProgressBar
, заключается в том, что вам нужно вызвать Drawable.setLevel()
в onDraw()
, чтобы вещь <rotate>
имела какой-либо эффект. ProgressBar
работает примерно так (дополнительный неважный код пропущен):
XML для рисования:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<rotate
android:drawable="@drawable/spinner_48_outer_holo"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0"
android:toDegrees="1080" />
</item>
<item>
<rotate
android:drawable="@drawable/spinner_48_inner_holo"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="720"
android:toDegrees="0" />
</item>
</layer-list>
In onDraw()
:
Drawable d = getDrawable();
if (d != null)
{
// Translate canvas so a indeterminate circular progress bar with
// padding rotates properly in its animation
canvas.save();
canvas.translate(getPaddingLeft(), getPaddingTop());
long time = getDrawingTime();
// I'm not sure about the +1.
float prog = (float)(time % ANIM_PERIOD+1) / (float)ANIM_PERIOD;
int level = (int)(MAX_LEVEL * prog);
d.setLevel(level);
d.draw(canvas);
canvas.restore();
ViewCompat.postInvalidateOnAnimation(this);
}
MAX_LEVEL
- это константа, которая всегда равна 10000 (согласно документам).
ANIM_PERIOD
- это период вашей анимации в миллисекундах.
К сожалению, так как вам нужно изменить onDraw()
, вы не можете просто поместить это рисование в ImageView
, так как ImageView
никогда не изменяет уровень рисования. Однако вы можете изменить уровень рисования с за пределами ImageView
. ProgressBar
(ab) использует AlphaAnimation
для установки уровня. Итак, вы бы сделали что-то вроде этого:
mMyImageView.setImageDrawable(myDrawable);
ObjectAnimator anim = ObjectAnimator.ofInt(myDrawable, "level", 0, MAX_LEVEL);
anim.setRepeatCount(ObjectAnimator.INFINITE);
anim.start();
Может сработать, но я не проверял.
Редактировать
На самом деле существует метод ImageView.setImageLevel()
, поэтому он может быть таким простым:
ObjectAnimator anim = ObjectAnimator.ofInt(myImageVew, "ImageLevel", 0, MAX_LEVEL);
anim.setRepeatCount(ObjectAnimator.INFINITE);
anim.start();