Drawable Вращающийся вокруг его центра Android - PullRequest
26 голосов
/ 27 сентября 2010

Я получаю странные результаты со следующим кодом:

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

Как правильно указать точку оси (центр рисунка)?

Ответы [ 3 ]

59 голосов
/ 27 сентября 2010

чувствую себя глупо! Приступил к работе, потратив некоторое время на прочтение документации:

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);
6 голосов
/ 24 июня 2011

Обратите внимание, что это не будет работать, если ваш объект имеет асимметричное заполнение (например, левое заполнение 5px и правое заполнение 0px), потому что заполнение считается частью объекта. Это означает, что вычисленный центр будет смещен.

Одним из решений этой проблемы является использование полей вместо отступов, если вы используете заполнение по причинам макета. Как говорит API относительно полей: «Это пространство находится за пределами этого представления». ( ViewGroup.MarginLayoutParams )

Это означает, что поля не будут вращаться, как отступы.

3 голосов
/ 23 августа 2016

Поскольку заголовок для этих вопросов Drawable Вращаясь вокруг его центра (и я искал именно его, не нашел его и должен был реализовать его сам), хотел бы опубликовать свое решение / ответ.

В итоге я написал собственный чертеж, который может обернуть любой объект и разрешить его вращение.Вот код:

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;
    }
}
...