java Android中图像的动画旋转
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27832881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Animate rotation of an image in Android
提问by rmoh21
I have a gear image which I want to continuously rotate about a fixed point.
Earlier I was accomplishing this by including the image in my Android class as an ImageView and applying a RotateAnimation to it.
@InjectView(R.id.gear00) ImageView gear00; RotateAnimation ra07 = new RotateAnimation(0, 359, 129, 186); ra07.setDuration(10000); ra07.setRepeatCount(RotateAnimation.INFINITE); ra07.setInterpolator(new LinearInterpolator()); gear00.setAnimation(ra07);
我有一个齿轮图像,我想围绕一个固定点连续旋转。
早些时候,我通过将图像作为 ImageView 包含在我的 Android 类中并对其应用 RotateAnimation 来完成此操作。
@InjectView(R.id.gear00) ImageView gear00; RotateAnimation ra07 = new RotateAnimation(0, 359, 129, 186); ra07.setDuration(10000); ra07.setRepeatCount(RotateAnimation.INFINITE); ra07.setInterpolator(new LinearInterpolator()); gear00.setAnimation(ra07);
Basically, I was injecting the ImageView into the class and applying a rotation animation.
基本上,我将 ImageView 注入到类中并应用旋转动画。
However, I dont have the luxury of using an ImageView anymore. I have to use a Bitmapand rotate it on the canvas.
但是,我不再有使用 ImageView 的奢侈了。我必须使用位图并在画布上旋转它。
How can I go about accomplishing what I was doing earlier in the onDraw()method with a bitmap rotating about a fixed point continiously on the canvas?
如何使用位图围绕画布上的固定点连续旋转来完成我之前在onDraw()方法中所做的事情?
Edit1:
编辑1:
I tried one of the suggestions mentioned below my code looks a little like the following
我尝试了下面提到的建议之一我的代码看起来有点像下面
in onCreate():
在 onCreate() 中:
Matrix matrix = new Matrix();
matrix.setRotate(10, 100, 200);
Then in onDraw() (where gear00Scaled is a bitmap to be rotated on the canvas):
然后在 onDraw() (其中 gear00Scaled 是要在画布上旋转的位图):
canvas.drawBitmap(gear00Scaled, matrix, new Paint());
canvas.drawBitmap(gear00Scaled, matrix, new Paint());
Another method I tried involved saving the canvas, rotating it, then restoring it:
我尝试的另一种方法是保存画布,旋转它,然后恢复它:
canvas.save();
canvas.rotate(10);
canvas.drawBitmap(gear00Scaled, 100, 200, null);
canvas.restore();
画布.save();
画布.旋转(10);
canvas.drawBitmap(gear00Scaled, 100, 200, null);
canvas.restore();
Neither seem to be working though!
两者似乎都没有工作!
采纳答案by yoah
In your onCreate() do
在你的 onCreate() 做
Matrix matrix = new Matrix();
And in onDraw
在 onDraw 中
float angle = (float) (System.currentTimeMillis() % ROTATE_TIME_MILLIS)
/ ROTATE_TIME_MILLIS * 360;
matrix.reset();
matrix.postTranslate(-source.getWidth() / 2, -source.getHeight() / 2);
matrix.postRotate(angle);
matrix.postTranslate(centerX, centerY)
canvas.drawBitmap(source, matrix, null);
invalidate(); // Cause a re-draw
ROTATE_TIME_MILLIS is the full circle time, e.g. 2000 is 2 seconds.
ROTATE_TIME_MILLIS 是整圈时间,例如 2000 是 2 秒。
回答by Tushar Gogna
Make an XML class (suppose: rotate.xml) and place it in res/anim folder and then write the following code in it:
创建一个 XML 类(假设:rotate.xml)并将其放在 res/anim 文件夹中,然后在其中编写以下代码:
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:interpolator="@android:anim/linear_interpolator"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:toDegrees="360" />
Then in your java class, do the following in OnCreate
:
然后在您的 java 类中,执行以下操作OnCreate
:
final Animation a = AnimationUtils.loadAnimation(CustomActivity.this,
R.anim.rotate);
a.setDuration(3000);
gear00.startAnimation(a);
OR
或者
To do it using bitmap, I hope the following sequence of code helps you:
要使用位图来做到这一点,我希望以下代码序列对您有所帮助:
Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, targetHeight, config);
Canvas canvas = new Canvas(targetBitmap);
Matrix matrix = new Matrix();
matrix.setRotate(mRotation,source.getWidth()/2,source.getHeight()/2);
canvas.drawBitmap(source, matrix, new Paint());
If you check the following method from:
如果您检查以下方法:
~frameworks\base\graphics\java\android\graphics\Bitmap.java
~frameworks\base\graphics\java\android\graphics\Bitmap.java
public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
Matrix m, boolean filter)
this would explain what it does with rotation and translate.
这将解释它对旋转和平移的作用。
回答by Ashok Kateshiya
I want to rotate a custom image as progress dialog in my application. You can use the code below to rotate an image:
我想在我的应用程序中将自定义图像旋转为进度对话框。您可以使用以下代码旋转图像:
RotateAnimation anim = new RotateAnimation(0.0f, 360.0f ,
Animation.RELATIVE_TO_SELF, .5f, Animation.RELATIVE_TO_SELF, .5f);
anim.setInterpolator(new LinearInterpolator());
anim.setRepeatCount(Animation.INFINITE);
anim.setDuration(1000);
imageView.setAnimation(anim);
imageView.startAnimation(anim);
回答by Whitney
Two things before the code:
代码前两件事:
- You can't use imageview at all at all? Cause you could link it to a canvas and use a bitmap, but it is still an imageview.
- I believe the main issue you are having is the other answer is not animating it and you are missing the call to invalidate() the view and redraw it as rotated.
- 你根本不能使用 imageview 吗?因为您可以将它链接到画布并使用位图,但它仍然是一个图像视图。
- 我相信您遇到的主要问题是另一个答案没有为其设置动画,并且您错过了对 invalidate() 视图的调用并将其重新绘制为旋转。
So there are two approaches: 1st is with the imageview, personally I think it is easier and nicer. Below is a method in my activity class and mLittleChef is an ImageView.
所以有两种方法:第一种是使用imageview,我个人认为它更容易和更好。下面是我的活动类中的一个方法,而 mLittleChef 是一个 ImageView。
public void doCanvas(){
//Create our resources
Bitmap bitmap = Bitmap.createBitmap(mLittleChef.getWidth(), mLittleChef.getHeight(), Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
final Bitmap chefBitmap = BitmapFactory.decodeResource(getResources(),R.drawable.dish_special);
//Link the canvas to our ImageView
mLittleChef.setImageBitmap(bitmap);
ValueAnimator animation= ValueAnimator.ofFloat(0, 359, 129, 186);
animation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (Float) animation.getAnimatedValue();
//Clear the canvas
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
canvas.save();
canvas.rotate(value, canvas.getWidth()/2, canvas.getHeight()/2);
canvas.drawBitmap(chefBitmap, 0, 0, null);
canvas.restore();
mLittleChef.invalidate();
}
});
animation.setInterpolator(new LinearInterpolator());
animation.setDuration(1000);
animation.start();
}
The other way to do it is with a custom canvas class. Instead of an ImageView, I create my own custom view class for ExampleDrawView mLittleChefDraw; in my layout. You will probably have to monkey with this one a bit to get exactly what you are looking for in terms of rotation, I made it just do a 360 degree turn using the middle of the canvas as the pivot point.
另一种方法是使用自定义画布类。我为 ExampleDrawView mLittleChefDraw 创建了自己的自定义视图类,而不是 ImageView;在我的布局中。您可能需要稍微调整一下,才能在旋转方面准确地获得您想要的东西,我只是使用画布的中间作为枢轴点进行了 360 度旋转。
public class ExampleDrawView extends View {
Bitmap bitmap;
Float mRotate= 0f;
Handler h;
//State variables
final int STATE_PAUSE = 2;
final int STATE_ROTATE = 3;
int STATE_CURRENT;
public ExampleDrawView(Context context, AttributeSet attrs) {
super(context, attrs);
h = new Handler();
bitmap= BitmapFactory.decodeResource(getResources(), R.drawable.dish_special);
STATE_CURRENT= STATE_PAUSE;
}
Runnable move = new Runnable() {
@Override
public void run() {
switch (STATE_CURRENT){
case STATE_ROTATE:
if (mRotate<360){
mRotate++;
invalidate();
}else{
STATE_CURRENT= STATE_PAUSE;
}
h.postDelayed(move, 20);
break;
}
}
};
public void startDrawing(){
if(STATE_CURRENT == STATE_PAUSE){
STATE_CURRENT= STATE_ROTATE;
mRotate=(float) 0;
h.postDelayed(move, 20);
}
}
@Override
protected void onDraw(Canvas canvas){
super.onDraw(canvas);
//change your rotate point here, i just made it the middle of the canvas
canvas.rotate(mRotate,getWidth()/2,getHeight()/2);
canvas.drawBitmap(bitmap, 0, 0, null);
}
}
}
And then back in the activity call this to start it:
然后回到活动中调用它来启动它:
public void doCanvasCustomView(){
mLittleChefDraw.startDrawing();
}