How Do I Use 'RotateDrawable'?

2019-02-08 15:48发布

Could anyone tell me how they have got 'RotateDrawable' to work whether it be from code or XML or both? The documentation on animating Drawables is pretty poor and animation only seems to work for images. I want to be able to animate all drawables. When i tried to get a RotateDrawble from XML is just causes an exception. What is the correct function to find a RotateDrawable from XML?

Many thanks

Kerubu

7条回答
乱世女痞
2楼-- · 2019-02-08 16:34

You have to animate the "level" property, where 0 is the start value and 10000 is the end value.

The below example animates from start to finish, you can reverse the animation easily with this method.

final RotateDrawable rotateDrawable = ...
ObjectAnimator.ofInt(rotateDrawable, "level", 0, 10000).start();
查看更多
SAY GOODBYE
3楼-- · 2019-02-08 16:42

I would like to add a full example of animating a progress icon on ImageView, it is based on Mark Hetherington answer.

So my animation looks as follows:

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
                 android:pivotX="50%"
                 android:pivotY="50%"
                 android:fromDegrees="0"
                 android:toDegrees="-360"
                 android:duration="100"
                 android:drawable="@drawable/ic_loop_black_24dp"
    />

icon comes from https://material.io/icons/

then my layout contains an ImageView as follows:

        <ImageView
            android:id="@+id/progress"
            android:layout_marginTop="0dp"
            android:layout_marginLeft="-3dp"
            android:layout_width="30dp"
            android:layout_height="30dp"

            android:visibility="gone"
            android:scaleType="fitCenter"
            android:background="@drawable/progress_anim"
            android:layout_gravity="center_horizontal|center_vertical"
            />

and finally in code when I need to show animation I do:

    RotateDrawable rotateDrawable = ((RotateDrawable)progressImage.getBackground());
    ObjectAnimator anim = ObjectAnimator.ofInt(rotateDrawable, "level", 0, 10000);
    anim.setDuration(1000);
    anim.setRepeatCount(ValueAnimator.INFINITE);
    anim.start();
查看更多
不美不萌又怎样
4楼-- · 2019-02-08 16:42

The following code returns a Drawable wrapper that rotates another Drawable programmatically:

Drawable rotateDrawable(Drawable d, final float angle) {
    // Use LayerDrawable, because it's simpler than RotateDrawable.
    Drawable[] arD = {
        d
    };
    return new LayerDrawable(arD) {
        @Override
        public void draw(Canvas canvas) {
            canvas.save();
            canvas.rotate(angle);
            super.draw(canvas);
            canvas.restore();
        }
    };
}
查看更多
冷血范
5楼-- · 2019-02-08 16:47

This is a good working example. Param duration is used to animate it.

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="4000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:toDegrees="720" >

    <shape
        android:innerRadius="20dp"
        android:shape="ring"
        android:thickness="4dp"
        android:useLevel="false" >
        <size
            android:height="48dp"
            android:width="48dp" />

        <gradient
            android:centerY="0.5"
            android:endColor="@android:color/white"
            android:startColor="#00ffffff"
            android:type="sweep"
            android:useLevel="false" />
    </shape>

</rotate>
查看更多
聊天终结者
6楼-- · 2019-02-08 16:49

I haven't worked with a RotateDrawable, but if you're simply trying to animate rotation on a graphic, you don't need it. Drawables with a 'level' like RotateDrawable are meant to convey information rather than animate views.

The following code rotates an ImageView around its center:

ImageView myImageView = (ImageView)findViewById(R.id.my_imageview);

AnimationSet animSet = new AnimationSet(true);
animSet.setInterpolator(new DecelerateInterpolator());
animSet.setFillAfter(true);
animSet.setFillEnabled(true);

final RotateAnimation animRotate = new RotateAnimation(0.0f, -90.0f,
    RotateAnimation.RELATIVE_TO_SELF, 0.5f, 
    RotateAnimation.RELATIVE_TO_SELF, 0.5f);

animRotate.setDuration(1500);
animRotate.setFillAfter(true);
animSet.addAnimation(animRotate);

myImageView.startAnimation(animSet);
查看更多
Lonely孤独者°
7楼-- · 2019-02-08 16:49

You could manually call RotatedDrawable.setLevel() to rotate the drawable, or you could read the code of ProgressBar, the indeterminate drawable is a LayerDrawable whose children were RotatedDrawable, like this one:

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

The rotate animation was driven by ProgressBar's onDraw method.

查看更多
登录 后发表回答