有人能告诉我如何让 RotateDrawable
工作,无论是通过代码还是XML?动画绘图的文档非常不完善,似乎只对图像有效。我想要能够动画化所有可绘制对象。当我尝试从XML中获取一个 RotateDrawble
时,它会导致异常。从XML找到 RotateDrawable
的正确函数是什么?
有人能告诉我如何让 RotateDrawable
工作,无论是通过代码还是XML?动画绘图的文档非常不完善,似乎只对图像有效。我想要能够动画化所有可绘制对象。当我尝试从XML中获取一个 RotateDrawble
时,它会导致异常。从XML找到 RotateDrawable
的正确函数是什么?
这里有一个不错的解决方案,可以为imageView添加一个旋转的drawable:
Drawable getRotateDrawable(final Bitmap b, final float angle) {
final BitmapDrawable drawable = new BitmapDrawable(getResources(), b) {
@Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(angle, b.getWidth() / 2, b.getHeight() / 2);
super.draw(canvas);
canvas.restore();
}
};
return drawable;
}
使用方法:
Bitmap b=...
float angle=...
final Drawable rotatedDrawable = getRotateDrawable(b,angle);
root.setImageDrawable(rotatedDrawable);
另一个选择:
private Drawable getRotateDrawable(final Drawable d, final float angle) {
final Drawable[] arD = { d };
return new LayerDrawable(arD) {
@Override
public void draw(final Canvas canvas) {
canvas.save();
canvas.rotate(angle, d.getBounds().width() / 2, d.getBounds().height() / 2);
super.draw(canvas);
canvas.restore();
}
};
}
此外,如果你希望旋转位图,但担心OOM,可以使用我制作的一个NDK解决方案这里
您需要为“level”属性创建动画,其中0是起始值,10000是结束值。
以下示例从开头到结尾进行动画处理,您可以使用此方法轻松地反转动画。
final RotateDrawable rotateDrawable = ...
ObjectAnimator.ofInt(rotateDrawable, "level", 0, 10000).start();
<?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"
/>
图标来自https://material.io/icons/
然后我的布局包含一个ImageView,如下所示:
<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"
/>
RotateDrawable rotateDrawable = ((RotateDrawable)progressImage.getBackground());
ObjectAnimator anim = ObjectAnimator.ofInt(rotateDrawable, "level", 0, 10000);
anim.setDuration(1000);
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.start();
RotateDrawable似乎不能进行动画。相反,您需要使用setLevel来改变可绘制对象的旋转。
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/your_drawable"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="360" />
设置级别将旋转可绘制对象:
final ImageView image = (ImageView)findViewById(R.id.imageView1);
final RotateDrawable drawable = (RotateDrawable)image.getDrawable();
drawable.setLevel(500);
<rotate>
标签做什么?您没有在任何地方进行膨胀。其次,我尝试将 Drawable 强制转换为 RotateDrawable,并得到以下强制转换异常
java.lang.ClassCastException: android.graphics.drawable.BitmapDrawable - Frank SposaroDrawable 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();
}
};
}
这是一个很好的工作示例。参数“duration”用于对其进行动画处理。
<?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>
我没有使用过RotateDrawable,但如果你只是想在图形上实现旋转动画,那么你不需要它。具有“级别”(level)的可绘制对象,如RotateDrawable,旨在传达信息而不是为了动画视图。
以下代码可以使ImageView围绕其中心旋转:
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);
既然你正在尝试使用Almero的Android手势检测器,我决定做同样的事情以找到一个合适的解决方案:
public class MainActivity extends Activity {
private RotateGestureDetector mRotateDetector;
private float mRotationDegrees = 0.f;
private static final float ROTATION_RATIO = 2;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRotateDetector = new RotateGestureDetector(getApplicationContext(), new RotateListener());
}
@Override
public boolean onTouchEvent(MotionEvent event) {
mRotateDetector.onTouchEvent(event);
return super.onTouchEvent(event);
}
private class RotateListener extends RotateGestureDetector.SimpleOnRotateGestureListener {
@Override
public boolean onRotate(RotateGestureDetector detector) {
mRotationDegrees -= detector.getRotationDegreesDelta();
ImageView v = (ImageView) findViewById(R.id.imageView);
// For NineOldAndroids library only!
ViewHelper.setRotation(v, mRotationDegrees * ROTATION_RATIO);
// For HONEYCOMB and later only!
v.setRotation(mRotationDegrees * ROTATION_RATIO);
return true;
}
}
}
你可以手动调用 RotatedDrawable.setLevel() 来旋转 Drawable,或者你可以查看 ProgressBar 的代码,不确定状态的 drawable 是一个 LayerDrawable,它的子项是 RotatedDrawable,像这样:
<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>
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<animated-rotate android:drawable="@drawable/ic_refresh" android:pivotX="50%" android:pivotY="50%" />
</item>
</selector>