【问题标题】:Animate rotation of an image in AndroidAndroid中图像的动画旋转
【发布时间】:2015-01-08 04:21:29
【问题描述】:
  • 我有一个齿轮图像,我想围绕一个固定点连续旋转。

  • 之前我是通过将图像作为 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);
    

基本上,我将 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();

但似乎都没有工作!

【问题讨论】:

  • 如果此位图显示在View 中,则需要重复重绘视图。

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


【解决方案1】:

制作一个 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());

如果您从以下方法检查:

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

这将解释它对旋转和平移的作用。

【讨论】:

  • 您的解释很有帮助。但是,我似乎无法让齿轮静止不动。我几乎遵循了您列出的第二种方法。我在 onDraw() 方法中创建位图和矩阵 - 然后在画布上绘制位图 - 位图确实绘制在正确的位置,但它不会旋转。想知道我是否遗漏了什么?
  • 你用矩阵的setRotate方法了吗?
  • 我已经用一些我正在玩的示例代码更新了我的原始问题。是的,我确实使用了矩阵的 setRotate,但不知何故,这并没有成功。
  • 那一点也不旋转? O.o
  • canvas.drawBitmap(gear00Scaled, 100, 200, null);之前致电canvas.concat(matrix);
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

    在你的 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 秒。

    【讨论】:

      【解决方案4】:

      代码前的两件事:

      1. 你根本不能使用imageview?因为您可以将其链接到画布并使用位图,但它仍然是图像视图。
      2. 我相信您遇到的主要问题是另一个答案是没有为其设置动画,并且您错过了调用 invalidate() 视图并将其重绘为旋转的调用。

      所以有两种方法: 第一个是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();
      }
      

      【讨论】:

        猜你喜欢
        • 2014-01-05
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 1970-01-01
        • 1970-01-01
        • 2011-04-15
        • 1970-01-01
        • 2015-07-24
        相关资源
        最近更新 更多