2010-09-27 33 views
25

Tôi nhận được kết quả kỳ lạ với đoạn mã sau:drawable Rotating xung quanh trung tâm của nó 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); 

Whats cách đúng để xác định các điểm trục (trung tâm của drawable)?

Trả lời

54

Cảm thấy ngu ngốc! Đã nhận nó để làm việc sau khi trải qua một thời gian đọc kỹ tài liệu:

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

Thêm "a.setInterpolator (LinearInterpolator mới());" làm cho vòng quay mượt mà hơn một chút. –

+1

Tôi muốn xoay 180 độ nhưng không lặp lại. sau khi xoay, đối tượng sẽ được trên trạng thái cuối cùng những gì tôi có nghĩa là nó sẽ không trở lại ở vị trí bắt đầu. Làm thế nào tôi có thể làm điều đó? –

+2

@Md Omar Faroque Anik: thêm "a.setFillAfter (true);" để thực hiện chuyển đổi liên tục và "a.setRepeatCount (0);" không lặp lại. – Bubu

5

Lưu ý rằng điều này sẽ không hoạt động nếu đối tượng của bạn có đệm không đối xứng (ví dụ như một lớp đệm bên trái của 5px và một lớp đệm bên phải của 0px), bởi vì đệm được coi là một phần của đối tượng. Có nghĩa là trung tâm tính toán sẽ được bù đắp.

Một giải pháp cho việc này là sử dụng lề thay vì đệm nếu bạn đang sử dụng đệm cho lý do bố cục. Như API nói về lề: "Không gian này nằm ngoài giới hạn của khung nhìn này." (ViewGroup.MarginLayoutParams)

Điều này có nghĩa là các lề sẽ không xoay thành đệm.

+0

Làm cách nào để tôi nói 'RotateAnimation' để xem xét Lợi nhuận? –

3

Tiêu đề cho câu hỏi này là Có thể vẽ Xoay quanh trung tâm (và tôi đang tìm kiếm chính xác, không tìm thấy và phải tự mình thực hiện) muốn đăng giải pháp/câu trả lời của tôi.

Tôi đã kết thúc bằng văn bản có thể vẽ tùy chỉnh có thể quấn bất kỳ hình vẽ nào và cho phép xoay vòng. Đây là mã:

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

@AnimatorSetter là gì? –

+0

Rất tiếc ... Đó chỉ là chú thích tùy chỉnh của tôi. Tôi sử dụng nó để chỉ ra cho ProGuard và Android studio rằng phương pháp này thực sự được sử dụng cho hoạt ảnh. (ObjectAnimator.ofFloat (this, "rotation", 0, 0), gọi setRotation trong khi thực hiện) – GregoryK

+0

Lớp này cần được giữ trong ProGuard và VectorDrawable sẽ gây ra sự cố trong Lollipop trước, nhưng không cần nó trừ khi bạn sử dụng các đối tượng vẽ vector . –

Các vấn đề liên quan