سؤال

أحصل على نتائج غريبة مع الكود التالي:

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

ما هي الطريقة الصحيحة لتحديد نقطة المحور (مركز السحب)؟

هل كانت مفيدة؟

المحلول

يشعر بالغباء! حصلت على العمل بعد قضاء بعض الوقت عن كثب في قراءة الوثائق:

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

نصائح أخرى

لاحظ أن هذا لن يعمل إذا كان للكائن الخاص بك حشوة غير متماثلة (على سبيل المثال حشوة يسارية من 5 بكسل وحشو يمين 0 بكسل) ، لأن الحشو يعتبر جزءًا من الكائن. مما يعني أن المركز المحسوب سيتم تعويضه.

أحد الحلول لهذا هو استخدام الهوامش بدلاً من الحشو إذا كنت تستخدم الحشو لأسباب تخطيط. كما تقول واجهة برمجة التطبيقات (API) بخصوص الهوامش: "هذه المساحة خارج حدود هذا الرأي". ((ViewGroup.MarginLayoutParams)

هذا يعني أن الهوامش لن تدور كما تفعل الحشو.

كعنوان لهذه الأسئلة يمكن رسمها تدور حول مركزها (وكنت أبحث تمامًا عن ذلك ، ولم أجدها واضطررت إلى تنفيذها بنفسي) يرغب في نشر الحل/إجابتي.

انتهى بي الأمر بكتابة رسم مخصص يمكنه لف أي رسم والسماح بالتناوب. هنا هو الرمز:

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;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top