如何正确创建自定义的动画可绘制对象?

android开发人员

背景

我一直在很多地方进行搜索,以查找如何为可绘制对象设置动画,而不对视图进行动画处理以及使用内置可绘制对象。

原因是我将需要在可绘制对象中准备自定义动画,以后可能会有不同的要求。

现在,我正在制作一个基本的动画可绘制对象,该对象在其中旋转一个给定的位图。

我已经在imageView上设置了它,但是我希望能够在任何类型的视图上使用它,即使是覆盖了onDraw函数的自定义视图也是如此。

问题

无论视图的大小如何,我都无法找到如何在不剪切的情况下显示可绘制对象的方法。这是我看到的:

在此处输入图片说明

代码

这是代码:

private class CircularAnimatedDrawable extends Drawable implements Animatable {
    private static final Interpolator ANGLE_INTERPOLATOR = new LinearInterpolator();
    private static final int ANGLE_ANIMATOR_DURATION = 2000;
    private final RectF fBounds = new RectF();
    private float angle = 0;
    private ObjectAnimator mObjectAnimatorAngle;
    private final Paint mPaint;
    private boolean mRunning;
    private final Bitmap mBitmap;

    public CircularAnimatedDrawable(final Bitmap bitmap) {
        this.mBitmap = bitmap;
        mPaint = new Paint();
        setupAnimations();
    }

    public float getAngle() {
        return this.angle;
    }

    public void setAngle(final float angle) {
        this.angle = angle;
        invalidateSelf();
    }

    @Override
    public Callback getCallback() {
        return mCallback;
    }

    @Override
    public void draw(final Canvas canvas) {
        canvas.save();
        canvas.rotate(angle);
        canvas.drawBitmap(mBitmap, 0, 0, mPaint);
        canvas.restore();
    }

    @Override
    public void setAlpha(final int alpha) {
        mPaint.setAlpha(alpha);
    }

    @Override
    public void setColorFilter(final ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }

    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }

    @Override
    protected void onBoundsChange(final Rect bounds) {
        super.onBoundsChange(bounds);
        fBounds.left = bounds.left;
        fBounds.right = bounds.right;
        fBounds.top = bounds.top;
        fBounds.bottom = bounds.bottom;
    }

    private void setupAnimations() {
        mObjectAnimatorAngle = ObjectAnimator.ofFloat(this, "angle", 360f);
        mObjectAnimatorAngle.setInterpolator(ANGLE_INTERPOLATOR);
        mObjectAnimatorAngle.setDuration(ANGLE_ANIMATOR_DURATION);
        mObjectAnimatorAngle.setRepeatMode(ValueAnimator.RESTART);
        mObjectAnimatorAngle.setRepeatCount(ValueAnimator.INFINITE);
    }

    @Override
    public void start() {
        if (isRunning())
            return;
        mRunning = true;
        mObjectAnimatorAngle.start();
        invalidateSelf();
    }

    @Override
    public void stop() {
        if (!isRunning())
            return;
        mRunning = false;
        mObjectAnimatorAngle.cancel();
        invalidateSelf();
    }

    @Override
    public boolean isRunning() {
        return mRunning;
    }

}

和用法:

    final ImageView imageView = (ImageView) findViewById(R.id.imageView);
    final Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.spinner_76_inner_holo);

    final CircularAnimatedDrawable circularAnimatedDrawable = new CircularAnimatedDrawable(bitmap);
    circularAnimatedDrawable.setCallback(imageView);
    circularAnimatedDrawable.start();
    imageView.setImageDrawable(circularAnimatedDrawable);

问题

如何设置使其适合视图?

我应该使用位图大小吗?fBounds?两个都?也许还有其他东西?

pskink

尝试使用此Drawable的修改版本:

class CircularAnimatedDrawable extends Drawable implements Animatable, TimeAnimator.TimeListener {
    private static final float TURNS_PER_SECOND = 0.5f;
    private Bitmap mBitmap;
    private boolean mRunning;
    private TimeAnimator mTimeAnimator = new TimeAnimator();
    private Paint mPaint = new Paint();
    private Matrix mMatrix = new Matrix();

    public CircularAnimatedDrawable(final Bitmap bitmap) {
        mBitmap = bitmap;
        mTimeAnimator.setTimeListener(this);
    }
    @Override
    public void draw(final Canvas canvas) {
        canvas.drawBitmap(mBitmap, mMatrix, mPaint);
    }
    @Override
    protected void onBoundsChange(Rect bounds) {
        Log.d(TAG, "onBoundsChange " + bounds);
        mMatrix.setRectToRect(new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight()),
                new RectF(bounds),
                Matrix.ScaleToFit.CENTER);
    }
    @Override
    public void onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime) {
        Rect b = getBounds();
        mMatrix.postRotate(360 * TURNS_PER_SECOND * deltaTime / 1000, b.centerX(), b.centerY());
        invalidateSelf();
    }
    @Override
    public void setAlpha(final int alpha) {
        mPaint.setAlpha(alpha);
    }
    @Override
    public void setColorFilter(final ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }
    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }
    @Override
    public void start() {
        if (isRunning())
            return;
        mRunning = true;
        mTimeAnimator.start();
        invalidateSelf();
    }
    @Override
    public void stop() {
        if (!isRunning())
            return;
        mRunning = false;
        mTimeAnimator.cancel();
        invalidateSelf();
    }
    @Override
    public boolean isRunning() {
        return mRunning;
    }
}

编辑:没有Animator内容的版本(使用[un] scheduleSelf),请注意,它使用View的Drawable.Callback机制,因此通常无法直接从onCreate启动,而View尚未附加处理程序

class CircularAnimatedDrawable extends Drawable implements Animatable, Runnable {
    private static final float TURNS_PER_SECOND = 0.5f;
    private static final long DELAY = 50;
    private Bitmap mBitmap;
    private long mLastTime;
    private boolean mRunning;
    private Paint mPaint = new Paint();
    private Matrix mMatrix = new Matrix();

    public CircularAnimatedDrawable(final Bitmap bitmap) {
        mBitmap = bitmap;
    }
    @Override
    public void draw(final Canvas canvas) {
        canvas.drawBitmap(mBitmap, mMatrix, mPaint);
    }
    @Override
    protected void onBoundsChange(Rect bounds) {
        Log.d(TAG, "onBoundsChange " + bounds);
        mMatrix.setRectToRect(new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight()),
                new RectF(bounds),
                Matrix.ScaleToFit.CENTER);
    }
    @Override
    public void setAlpha(final int alpha) {
        mPaint.setAlpha(alpha);
    }
    @Override
    public void setColorFilter(final ColorFilter cf) {
        mPaint.setColorFilter(cf);
    }
    @Override
    public int getOpacity() {
        return PixelFormat.TRANSPARENT;
    }
    @Override
    public void start() {
        if (isRunning())
            return;
        mRunning = true;
        mLastTime = SystemClock.uptimeMillis();
        scheduleSelf(this, 0);
        invalidateSelf();
    }
    @Override
    public void stop() {
        if (!isRunning())
            return;
        mRunning = false;
        unscheduleSelf(this);
        invalidateSelf();
    }
    @Override
    public boolean isRunning() {
        return mRunning;
    }
    @Override
    public void run() {
        long now = SystemClock.uptimeMillis();
        Rect b = getBounds();
        long deltaTime = now - mLastTime;
        mLastTime = now;
        mMatrix.postRotate(360 * TURNS_PER_SECOND * deltaTime / 1000, b.centerX(), b.centerY());
        scheduleSelf(this, now + DELAY);
        invalidateSelf();
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

用动画创建自定义视图

来自分类Dev

对象(动物)的自定义动画

来自分类Dev

如何使自定义对象可迭代?

来自分类Dev

如何正确扩展LinearLayout以创建自定义视图

来自分类Dev

如何正确创建带有消息的自定义异常?

来自分类Dev

创建自定义形状/可绘制-6面按钮

来自分类Dev

JavaFX-如何创建简单的自定义绘制控件?

来自分类Dev

如何在运行时自定义XML中定义的自定义可绘制对象?

来自分类Dev

Android切换自定义左右可绘制对象

来自分类Dev

Android-具有形状可绘制对象和渐变的自定义按钮

来自分类Dev

使用ImageView自定义可绘制

来自分类Dev

Android:带有自定义可绘制对象的SeekBar

来自分类Dev

如何创建自定义的fabricjs对象?

来自分类Dev

API 23以下的自定义可绘制匹配父对象中的位图

来自分类Dev

如何为自定义视图创建缩放动画效果

来自分类Dev

Android:自定义seekbar进度可绘制对象渲染不正确

来自分类Dev

所需的方向-如何创建可自定义的文件?

来自分类Dev

android seekbar自定义可绘制

来自分类Dev

如何使自定义对象可迭代?

来自分类Dev

如何使用UIView创建自定义翻转动画

来自分类Dev

可绘制的Android自定义Seekbar

来自分类Dev

自定义数据源对象未正确创建

来自分类Dev

如何用动画创建自定义动作菜单

来自分类Dev

如何使用Birt创建可自定义的报告

来自分类Dev

如何使用自定义可绘制对象设置初始评级栏进度

来自分类Dev

如何自定义“可创建”上的“x”图标?

来自分类Dev

如何使用图像标记创建自定义可绘制图钉

来自分类Dev

创建自定义可绘制形状

来自分类Dev

绘制自定义视图的正确方法?

Related 相关文章

热门标签

归档