Android中图像的旋转动画

时间:2015-01-08 04:21:29

标签: java android android-layout android-canvas wear-os

  • 我有一个齿轮图像,我想连续围绕一个固定点旋转。

  • 之前我通过在我的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);
    

基本上,我将ImageView注入到类中并应用旋转动画。

然而,我再也没有使用ImageView的奢侈了。我必须使用 Bitmap 并在画布上旋转它。

如何在 onDraw()方法中使用位图在画布上连续旋转固定点来完成我之前正在做的事情?

编辑1:

我尝试了下面提到的建议之一,我的代码看起来有点像下面的

onCreate()中的

Matrix matrix = new Matrix();
matrix.setRotate(10, 100, 200);

然后在onDraw()中(其中gear00Scaled是在画布上旋转的位图):

  

canvas.drawBitmap(gear00Scaled,matrix,new Paint());

我试过的另一种方法是保存画布,旋转它,然后恢复它:

  

canvas.save();
  canvas.rotate(10);
  canvas.drawBitmap(gear00Scaled,100,200,null);
  canvas.restore();

似乎都没有工作!

4 个答案:

答案 0 :(得分:9)

创建一个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" />

然后在您的java类中,在OnCreate中执行以下操作:

final Animation a = AnimationUtils.loadAnimation(CustomActivity.this,
                R.anim.rotate);
        a.setDuration(3000);
        gear00.startAnimation(a);

要使用位图,我希望以下代码序列可以帮助您:

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

如果您从以下方法检查以下方法:

  

〜框架\基\图形\ java中\机器人\图形\ Bitmap.java

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,
        Matrix m, boolean filter)

这可以解释它对旋转和翻译的作用。

答案 1 :(得分:4)

我想在我的应用程序中将自定义图像旋转为进度对话框。您可以使用以下代码旋转图像:

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

答案 2 :(得分:2)

在你的onCreate()中

Matrix matrix = new Matrix();

在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是整圈时间,例如2000年是2秒。

答案 3 :(得分:1)

代码前面的两件事:

  1. 根本不能使用imageview吗?因为你可以将它链接到画布并使用位图,但它仍然是一个imageview。
  2. 我相信你遇到的主要问题是另一个答案是没有动画它,你错过了使视图无效的调用,并将其重绘为旋转。
  3. 所以有两种方法: 第一是使用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();
    }
    

    另一种方法是使用自定义画布类。我为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);
    }
    

    }

    然后回到活动中调用它来启动它:

    public void doCanvasCustomView(){
        mLittleChefDraw.startDrawing();
    }