2010-09-27 6 views
25

estoy consiguiendo resultados extraños con el siguiente código:Disponibles gira alrededor de su centro de Android

iv = (ImageView) findViewById(R.id.iv); 
     iv.setImageResource(R.drawable.spinner_white_76); 

     Animation a = new RotateAnimation(0.0f, 360.0f, 
       Animation.RELATIVE_TO_SELF, iv.getDrawable() 
         .getIntrinsicWidth()/2, Animation.RELATIVE_TO_SELF, 
       iv.getDrawable().getIntrinsicHeight()/2); 
     a.setRepeatCount(-1); 
     a.setDuration(1000); 

     iv.startAnimation(a); 

¿Cuál es la manera correcta para especificar el punto del eje (centro de la estirable)?

Respuesta

54

¡Siéntete estúpido! ¡Gracias al trabajo después de pasar algún tiempo a la lectura de cerca la documentación:

Animation a = new RotateAnimation(0.0f, 360.0f, 
       Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 
       0.5f); 
     a.setRepeatCount(-1); 
     a.setDuration(1000); 
+16

Adición "a.setInterpolator (nueva LinearInterpolator());" hace que la rotación sea un poco más suave. –

+1

Quiero girar 180 grados pero no repetir. después de la rotación, el objeto estará en estado final, lo que quiero decir que no volverá a la posición inicial. ¿Cómo puedo hacer eso? –

+2

@Md Omar Faroque Anik: agregar "a.setFillAfter (true);" para hacer que la transformación sea persistente y "a.setRepeatCount (0);" para no repetir – Bubu

5

Tenga en cuenta que esto no funcionará si el objeto tiene un acolchado asimétrica (por ejemplo, un relleno a la izquierda de 5px y un relleno derecho de 0px), porque el acolchado se considera parte del objeto. Lo que significa que el centro computado se compensará.

Una solución para esto es usar márgenes en lugar de relleno si está utilizando relleno por motivos de diseño. Como dice la API sobre los márgenes: "Este espacio está fuera de los límites de esta vista". (ViewGroup.MarginLayoutParams)

Esto significa que los márgenes no girarán como lo hace el relleno.

+0

¿Cómo le diría a 'RotateAnimation' que considere Márgenes? –

3

Como el título de esta pregunta es Drawable Girando alrededor de su centro (y estaba buscando exactamente, no lo había encontrado y tuve que implementarlo por mi cuenta) me gustaría publicar mi solución/respuesta.

Terminé escribiendo drawable personalizado que puede envolver cualquier drawable y permitir su rotación. Aquí está el código:

public class RotatableDrawable extends DrawableWrapper { 

    private float rotation; 
    private Rect bounds; 
    private ObjectAnimator animator; 
    private long defaultAnimationDuration; 

    public RotatableDrawable(Resources resources, Drawable drawable) { 
     super(vectorToBitmapDrawableIfNeeded(resources, drawable)); 
     bounds = new Rect(); 
     defaultAnimationDuration = resources.getInteger(android.R.integer.config_mediumAnimTime); 
    } 

    @Override 
    public void draw(Canvas canvas) { 
     copyBounds(bounds); 
     canvas.save(); 
     canvas.rotate(rotation, bounds.centerX(), bounds.centerY()); 
     super.draw(canvas); 
     canvas.restore(); 
    } 

    public void rotate(float degrees) { 
     rotate(degrees, defaultAnimationDuration); 
    } 

    public void rotate(float degrees, long millis) { 
     if (null != animator && animator.isStarted()) { 
      animator.end(); 
     } else if (null == animator) { 
      animator = ObjectAnimator.ofFloat(this, "rotation", 0, 0); 
      animator.setInterpolator(new AccelerateDecelerateInterpolator()); 
     } 
     animator.setFloatValues(rotation, degrees); 
     animator.setDuration(millis).start(); 
    } 

    @AnimatorSetter 
    public void setRotation(float degrees) { 
     this.rotation = degrees % 360; 
     invalidateSelf(); 
    } 

    /** 
    * Workaround for issues related to vector drawables rotation and scaling: 
    * https://code.google.com/p/android/issues/detail?id=192413 
    * https://code.google.com/p/android/issues/detail?id=208453 
    */ 
    private static Drawable vectorToBitmapDrawableIfNeeded(Resources resources, Drawable drawable) { 
     if (drawable instanceof VectorDrawable) { 
      Bitmap b = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888); 
      Canvas c = new Canvas(b); 
      drawable.setBounds(0, 0, c.getWidth(), c.getHeight()); 
      drawable.draw(c); 
      drawable = new BitmapDrawable(resources, b); 
     } 
     return drawable; 
    } 
} 
+0

¿Qué es @AnimatorSetter? –

+0

Vaya ... Es solo mi anotación personalizada. Lo uso para indicar a ProGuard y Android Studio que este método se usa realmente para la animación. (ObjectAnimator.ofFloat (esto, "rotación", 0, 0); invoca setRotation durante la ejecución) – GregoryK

+0

Esta clase debe mantenerse en ProGuard y VectorDrawable provocará un bloqueo en pre Lollipop, pero no lo necesita a menos que use el vector dibujable . –

Cuestiones relacionadas