android 使用SurfaceView绘制一个简单动画控件

绘制1. 创建一个Circle继承自SurfaceView,让surfaceview能够获取canvas,需要实现这个Callback接口,这样在surfaceview准备好了之后才能进行绘制。这里的图是要让圆圈在外面不断的进行绘制,就是蓝色的那个圆圈去动态变化,知道包围整个圆

下面是创建circle类继承自surfaceview并且实现了surfaceview的callback接口

在surfaceview构造方法中设置callback监听为当前surfaceview

实现接口之后先获取surfaceview的宽高,并且调用surfaceview准备好了的接口,这个接口暴露给外面调用者告诉他们surfaceview准备好了可以开始绘制了

接下来看一下绘制线程中绘制圆

线程中有一个绘制circle的方法,在线程run中我们会使用一个while循环一直调用这个方法这样就达到了在圆的外面绘制圆圈的目的。绘制的时候要注意的几点

1. 通过旋转-90度坐标达到圆圈的0度是在竖直向上的方向

2. 前面在获取holder的时候为了让surfaceview本身的黑色背景消失添加的两句代码

3. 绘制文字,文字有上下的通过descent的长度是负数,ascent是正数,descent加上ascent就得到中间a字母的底层那个高度到黄色的baseline的高度,这个计算的长度再除以2就得到字符串的中心了

下面是绘制圆圈的代码

// 绘制圆圈
        private void drawCircle() {
            mListener.onAnimationRunning(Circle.this);
            Canvas canvas = mHolder.lockCanvas();
            if (canvas == null) {
                return;
            }
            canvas.drawRect(0, 0, mWidth, mHeight, mClearPaint);
            canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);

            canvas.save();
            canvas.scale(0.9f, 0.9f, mWidth * 1f / 2, mHeight * 1f / 2);
            canvas.drawCircle(mWidth * 1.0f / 2, mHeight * 1.0f / 2, mWidth * 1.0f / 2, mPaint);
            float centerY = mHeight * 1f / 2;
            // 这个是获取每个文字的宽度,那么怎么知道有几个文字呢?
            float ascent = mTextPaint.ascent();  // 正数
            float descent = mTextPaint.descent();  // 负数
            float textHeight = (ascent + descent) / 2;
//            float widths[] = new float[2];
//            mTextPaint.getTextWidths(TEXT_CIRCLE, widths);
            canvas.drawText(TEXT_CIRCLE, (float) (mWidth * 0.1)/2, centerY -textHeight, mTextPaint);
            canvas.restore();
            // 旋转坐标画圆圈
            canvas.save();
            canvas.rotate(-90, mWidth / 2, mHeight / 2);
            RectF rectF = new RectF((float) (mWidth / 2 * 0.1) / 2, (float) (mWidth / 2 * 0.1) / 2, mWidth - (float) (mWidth / 2 * 0.1) / 2, mHeight - (float) (mWidth / 2 * 0.1) / 2);
            canvas.drawArc(rectF, 0, mDegree, false, mArcPaint);
            canvas.restore();

            mHolder.unlockCanvasAndPost(canvas);
        }

在绘图线程的run方法方法中通过循环调用drawcircle来绘制圆圈,用一个标志来判断动画是否结束,在动画开始和结束调用接口的开始和结束方法暴露给外面调用这个view的对象,这样在完成动画之后能够进行其他的动作

下面是动画执行过程的接口, 包括动画的四个阶段,主要在prepared阶段可以调用开始动画的方法,开始动画就是开启一个动画绘制线程并且start即可

开始动画

下面是使用,在layout布局中添加一个circle的控件,然后获取到这个控件并且设置一下动画的监听,在准备好的监听中就可以开始动画了

 Circle下载地址

原文地址:https://www.cnblogs.com/xxss0903/p/5957672.html