简体   繁体   English

Android中图像的旋转动画

[英]Animate rotation of an image in Android

  • 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. 之前我通过在我的Android类中将图像作为ImageView包含并对其应用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. 但是,我再也没有使用ImageView的奢侈了。 I have to use a Bitmap and rotate it on the canvas. 我必须使用Bitmap并在画布上旋转它。

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

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.save();
canvas.rotate(10); canvas.rotate(10);
canvas.drawBitmap(gear00Scaled, 100, 200, null); canvas.drawBitmap(gear00Scaled,100,200,null);
canvas.restore(); canvas.restore();

Neither seem to be working though! 似乎都没有工作!

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 〜框架\\基\\图形\\ java中\\机器人\\图形\\ 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. 这可以解释它对旋转和翻译的作用。

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

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, eg 2000 is 2 seconds. ROTATE_TIME_MILLIS是整圈时间,例如2000是2秒。

Two things before the code: 代码前面有两件事:

  1. You can't use imageview at all at all? 根本不能使用imageview吗? Cause you could link it to a canvas and use a bitmap, but it is still an imageview. 因为您可以将它链接到画布并使用位图,但它仍然是一个imageview。
  2. 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. 我相信你遇到的主要问题是另一个答案是没有动画它,你错过了调用invalidate()视图并将其重绘为旋转。

So there are two approaches: 1st is with the imageview, personally I think it is easier and nicer. 所以有两种方法:第一种是使用imageview,我个人觉得它更简单,更好。 Below is a method in my activity class and mLittleChef is an 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; 我为ExampleDrawView mLittleChefDraw创建了自己的自定义视图类,而不是ImageView; 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. 你可能不得不用这一个来实现你在旋转方面正确寻找的东西,我只是用画布的中间作为枢轴点进行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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM