Canvas

来源:互联网 发布:淘宝图片包是什么 编辑:程序博客网 时间:2024/05/01 19:17



一.drawCircle

(1)Fill And Stroke

public class CanvasView extends View {    private Paint mPaint;    private Context mContext;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mContext = context;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int roundWidth = dp2px(20);        float center = getWidth() / 2;        mPaint.setColor(Color.BLUE);

mPaint.setStyle(Paint.Style.FILL_AND_STROKE);

mPaint.setStrokeWidth(roundWidth);        //去掉锯齿        mPaint.setAntiAlias(true);        //所画圆的中心 X坐标        //所画圆的中心 Y坐标        //所画圆的半径        //画圆要用的画笔        //drawCircle(float cx, float cy, float radius, Paint paint)        canvas.drawCircle(center, center, center - roundWidth / 2, mPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}

(2)Fill

<pre name="code" class="java">@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    int roundWidth = dp2px(20);    float center = getWidth() / 2;    mPaint.setColor(Color.BLUE);

mPaint.setStyle(Paint.Style.FILL);

mPaint.setStrokeWidth(roundWidth);    //去掉锯齿    mPaint.setAntiAlias(true);    //所画圆的中心 X坐标    //所画圆的中心 Y坐标    //所画圆的半径    //画圆要用的画笔    //drawCircle(float cx, float cy, float radius, Paint paint)    canvas.drawCircle(center, center, center - roundWidth / 2, mPaint);}

(3)Stroke

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    int roundWidth = dp2px(20);    float center = getWidth() / 2;    mPaint.setColor(Color.BLUE);
mPaint.setStyle(Paint.Style.STROKE);
 mPaint.setStrokeWidth(roundWidth);    //去掉锯齿    mPaint.setAntiAlias(true);    //所画圆的中心 X坐标    //所画圆的中心 Y坐标    //所画圆的半径    //画圆要用的画笔    //drawCircle(float cx, float cy, float radius, Paint paint)    canvas.drawCircle(center, center, center - roundWidth / 2, mPaint);}

(4)半径问题

之前一直觉得如果一个圆的半径是R,画笔的宽度是D,那么这个宽度是圆的半径内还是半径外?

下面展示的结果是,半径内外各一半D/2,所以我们只要用宽度为D的画笔画半径为R-D/2的圆效果就是半径为R的圆

设置的画笔的宽度(setStrokeWidth,这个宽度是半径内一半,半径外一半)





二.drawLine  drawText

public class CanvasView extends View {    private Paint mPaint;    private Paint mtextPaint;    private Context mContext;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mContext = context;        mtextPaint = new Paint();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int roundWidth = dp2px(20);        float center = getWidth() / 2;        float lineLength = dp2px(20);        mPaint.setColor(Color.BLUE);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(0);

 /**
 * 设置字体参数
 * */

  mtextPaint.setColor(Color.RED);        mtextPaint.setStyle(Paint.Style.STROKE);        mtextPaint.setTextSize(dp2px(18));        mtextPaint.setTypeface(Typeface.DEFAULT_BOLD);
  /**
   * 画线:在view的中心点画个坐标轴
   * */

canvas.translate(getWidth() / 2, getHeight() / 2);

//这时候(0,0)就是center的坐标!!!!!!

 //drawLine(float startX, float startY, float stopX, float stopY, Paint paint)        canvas.drawLine(0, 0, center + lineLength, 0, mPaint);        canvas.drawLine(0, 0, 0, center + lineLength, mPaint);

 /**
   * 画出两个字母X,y
   * */

  <span style="white-space:pre"></span>String strX = "X";        float strXSize = mtextPaint.measureText(strX);
 //这时候坐标轴中心在这个View的中点
canvas.drawText(strX, center - dp2px(20), -dp2px(10), mtextPaint);        String strY = "Y";//        float strXSize = mtextPaint.measureText(strX);        canvas.drawText(strY, -dp2px(10), center - dp2px(20), mtextPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}


(2).drawText产生的文字的问题

public class CanvasView extends View {    private Paint mPaint;    private Context mContext;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mContext = context;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int TextSize = dp2px(20);        float center = getWidth() / 2;        mPaint.setColor(Color.BLUE);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setTypeface(Typeface.DEFAULT_BOLD);        mPaint.setTextSize(TextSize);        //去掉锯齿        mPaint.setAntiAlias(true);        String textOne = "one";        String textTwo = "two";        float textOneSize = mPaint.measureText(textOne);        canvas.translate(center, center);        canvas.drawText(textOne, TextSize / 2, TextSize / 2, mPaint);        canvas.rotate(90);        canvas.drawText(textTwo, TextSize / 2, TextSize / 2, mPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}


三.drawArc

public class CanvasView extends View {    private Paint mPaint;    private Context mContext;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mContext = context;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int radius = dp2px(150) / 2;        int roundWidth = dp2px(20);        int center = getWidth() / 2;        mPaint.setColor(Color.BLUE);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(roundWidth);        //画个弧形        RectF oval = new RectF(center - radius                , center - radius                , center + radius                , center + radius);
/**
         * drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)
         * Draw the specified arc, which will be scaled to fit inside the specified oval.
         * 圆弧是内嵌于这个矩形的
         * */
        //-180开始转    转60度     true(画成扇形)  false只画弧

//-180开始转    转60度     true(画成扇形)  false只画弧        canvas.drawArc(oval, -180, 60, true, mPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}

我觉得最难理解就是这个矩形跟圆的关系,下面就是他们之间的关系!!!

四.CanvasRotate(Canva的旋转)

public class CanvasView extends View {    private Paint mPaint;    private Context mContext;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mContext = context;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        /**         * 本身矩形框的宽高就是 150dp  150dp         * */        //这个就把坐标系的原点改变为当前view的中心点(默认为左上角的顶点)        //!!!!!!!!!!!!!!!!!!!!!        canvas.translate(getWidth() / 2, getHeight() / 2);        /**         * 画一个蓝色的矩形         * */        mPaint.setColor(Color.BLUE);        mPaint.setStyle(Paint.Style.STROKE);

  //先画蓝色矩形

canvas.drawRect(dp2px(0), dp2px(0), dp2px(70), dp2px(50), mPaint);        /**         * 画一个红色的矩形         * */        //旋转画布        canvas.rotate(90);        //再画红色矩形        mPaint.setColor(Color.RED);        canvas.drawRect(dp2px(0), dp2px(0), dp2px(70), dp2px(50), mPaint);        /**         *         * 可以看出画布的坐标被移动的90度,画布没有动!!!!!!!         * */    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}
可以看出画布的坐标被移动的90度,画布没有动!!!!!!!

画布的坐标被转了90度,画布本身没有转


五.Canvas Save Rotate(Canva的旋转和Save)

canvasRotate  canvas转动  然后只是坐标变了

如果调用restore次数多于save就会报错!!!!

public class CanvasView extends View {    private Paint mPaint;    private Context mContext;    private Paint mTextPaint;    /**     * 圆环中间百分号颜色     */    private int percentColor;    /**     * 圆环中间百分号尺寸     */    private int percentSize;    public CanvasView(Context context) {        super(context);        init(context);    }    public CanvasView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public CanvasView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mPaint = new Paint();        mTextPaint = new Paint();        mContext = context;        // “%”符号颜色、尺寸        percentColor = Color.parseColor("#ff0000");        percentSize = (int) dp2px(20);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        mTextPaint.setStrokeWidth(0);        mTextPaint.setColor(percentColor);        mTextPaint.setTextSize(percentSize);        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);        // 矩形宽度        int lenght = dp2px(50);        /**         * 坐标系原点变成了View的原点,不再是默认的View左上角         *         * */        canvas.translate(getWidth() / 2, getHeight() / 2);        // 第一个黑色矩形        canvas.drawRect(-lenght, -lenght, lenght, lenght, mPaint);        // 保存x轴方向为3点钟方向的坐标        canvas.save();        /**         * 旋转坐标轴         * 坐标系顺时针转了45度         * */        canvas.rotate(45);        mPaint.setColor(Color.BLUE);        // 第二个蓝色矩形        canvas.drawRect(-lenght, -lenght, lenght, lenght, mPaint);        /**         * 恢复坐标轴(刚才偏移了45度),变成了x水平         * */        canvas.restore();        mPaint.setColor(Color.RED);        // 绘制坐标轴        canvas.drawLine(0, 0, 300, 0, mPaint);        canvas.drawText("x", dp2px(50), 0, mTextPaint);        canvas.drawLine(0, 0, 0, 300, mPaint);        canvas.drawText("y", 0, dp2px(50), mTextPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}


六.drawOval (画一个渐变色的圆,oval其实是椭圆的意思)

public class ZhiMaView extends View {    private Context mContext;    private final int[] mColors = new int[]{0xffff0000, 0xffffff00, 0xff00ff00,            0xff00ffff, 0xff0000ff, 0xffff00ff};// 渐变色环颜色    private Paint mPaint;    public ZhiMaView(Context context) {        super(context);        init(context);    }    public ZhiMaView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public ZhiMaView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        this.mContext = context;        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        int CENTER_X = getWidth() / 2;/** *  public SweepGradient (float cx, float cy, int[] colors, float[] positions) Added in API level 1 A subclass of Shader that draws a sweep gradient around a center point. Parameters cx    The x-coordinate of the center cy    The y-coordinate of the center colors    The colors to be distributed between around the center. There must be at least 2 colors in the array. positions     May be NULL. The relative position of each corresponding color in the colors array, beginning with 0 and ending with 1.0. If the values are not monotonic, the drawing may produce unexpected results. If positions is NULL, then the colors are automatically spaced evenly. * * */        //不太理解这个//围绕着一个中心点用着色器画渐变色        //A subclass of Shader that draws a sweep gradient around a center point.        Shader s = new SweepGradient(0, 0, mColors, null);        mPaint.setShader(s);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(40);        float r = CENTER_X - mPaint.getStrokeWidth() / 2;        canvas.save();        canvas.translate(CENTER_X, CENTER_X);// 移动中心        //canvas.rotate(150);        canvas.drawOval(new RectF(-r, -r, r, r), mPaint);// 画出色环和中心园        canvas.restore();    }}

七.DrawBitmap

public class BitmapView extends View {    private Bitmap bitmap;    private Paint bitmapPaint= new Paint();    public BitmapView(Context context) {        super(context);        init();    }    public BitmapView(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public BitmapView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init() {        bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.home_my_try_click);        bitmapPaint.setAntiAlias(true);        bitmapPaint.setColor(Color.BLACK);        bitmapPaint.setStyle(Paint.Style.FILL);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawBitmap(bitmap,0,0,bitmapPaint);    }}

//布局文件activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"                xmlns:tools="http://schemas.android.com/tools"                android:layout_width="match_parent"                android:layout_height="match_parent"                tools:context=".MainActivity">            <com.weixin.drawbitmap.view.BitmapView                android:layout_width="300dp"                android:layout_height="300dp"/></RelativeLayout>


这里设置是从0,0开始画

这个时候这个viewcenter in Parent ,也是从(0,0)这个时候这个0,0是相对他的容器



(1)setTranslatepreTranslate还有postTranslate 之间的区别

<1>setTranslate

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Matrix matrix=new Matrix();    /**     *  matrix.setScale(interpolatedTime, interpolatedTime);        matrix.preTranslate(-centerX, -centerY);        matrix.postTranslate(centerX, centerY);        经常在中心缩放的应用中看到这段代码.        preTranslate是指在setScale前,平移,postTranslate是指在setScale后平移        注意他们参数是平移的距离,而不是平移目的地的坐标!!!!!        由于缩放是以(0,0)为中心的,所以为了把界面的中心与(0,0)对齐,就要preTranslate(-centerX, -centerY),        setScale完成后,调用postTranslate(centerX, centerY),再把图片移回来,这样看到的动画效果就是activity的界面图片从中心不停的缩放了         注:centerX和centerY是界面中心的坐标         因为矩阵变换设计到合并矩阵的情况,所以才分了pre和post函数,可以参照skia库中SkMatrix.cpp函数原型。pre表示回受到先前的变换的影响,而post不会。比如         (1)         matrxi.scale(0.5, 0.5);         matrix.preTranslate(100, 0);         (2)         matrix.scale(0.5, 0.5);         matrix.postTranslate(100, 0);         第一段代码缩放后会再平移100*0.5=50的距离,而第二段代码缩放后会平移坐标给定的100的距离。     *     * */    matrix.postScale(0.5f, 0.5f);
matrix.preTranslate(240,0); //实际移动的距离是120 = 240 * 0.5f;
    canvas.drawBitmap(bitmap,matrix,bitmapPaint);}

<2>preTranslate

@Overrideprotected void onDraw(Canvas canvas) {    super.onDraw(canvas);    Matrix matrix=new Matrix();    matrix.postScale(0.5f, 0.5f);
matrix.postTranslate(120,0); 
    canvas.drawBitmap(bitmap,matrix,bitmapPaint);}

<1>和<2>的效果都是一样的如下图






八.DrawClock()画一个钟(一个简单的实践)

public class ClockView extends View {    private Context mContext;    private Paint mPaint;    private Paint mTextPaint;    public ClockView(Context context) {        super(context);        init(context);    }    public ClockView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public ClockView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init(context);    }    private void init(Context context) {        mContext = context;        mPaint = new Paint();        mTextPaint = new Paint();    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        /**         * 先画一个大圆,默认坐标系原点是View的左上角         * */        int center = getWidth() / 2;        int roundWidth = dp2px(10);        int radius = getWidth() / 2 - dp2px(100) / 2 - roundWidth / 2;        int textWidth = dp2px(10);        //去掉锯齿        mPaint.setAntiAlias(true);        mPaint.setColor(Color.BLUE);        mPaint.setStyle(Paint.Style.STROKE);        mPaint.setStrokeWidth(roundWidth);        canvas.drawCircle(center, center, radius, mPaint);        /**         *画刻度还有数字         * */        //刻度线不要那么宽        mPaint.setStrokeWidth(0);        //刻度线换一种颜色        // mPaint.setColor(Color.BLACK);        mTextPaint.setStrokeWidth(0);        mTextPaint.setColor(Color.RED);        mTextPaint.setTextSize(textWidth);        mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);        canvas.translate(center, center);        //这时候坐标系  X轴在三点钟方向 Y轴在六点钟方向        canvas.save();        //坐标系原点从原来的View的左上角顶点移到View的中心        //从刻度1开始画(坐标轴逆时针转60)        canvas.rotate(-60);        for (int i = 0; i < 60; i++) {            if (i % 5 == 0) {                //每五个小格就是一个大格,所以画长刻度                canvas.drawLine(radius, 0, radius + dp2px(25), 0, mPaint);                //这时候坐标系 X轴在一点钟方向  Y轴在4点钟方向                //这个save保存了每一小格转了6度                canvas.save();                //画完大刻度就把大刻度的数字标一下(这里需要注意一下,需要数字朝向View的中心)                //开始移动坐标系到接近数字的地方                canvas.translate(radius + dp2px(30), 0);                //为了让数字的底部对着View的中心,所以canvas要顺时针转90度                canvas.rotate(90);                String str = String.valueOf(i / 5 + 1);                float strSize = mPaint.measureText(str);                canvas.drawText(str, -strSize / 2, 0, mTextPaint);                //回到//这时候坐标系 X轴在一点钟方向  Y轴在4点钟方向                canvas.restore();            } else {                //其他的情况下就是一个小格,所以画短刻度                canvas.drawLine(radius, 0, radius + dp2px(15), 0, mPaint);            }            //每画完一次刻度就顺时针转6度(也就是下一个刻度)            canvas.rotate(360 / 60f);        }        //这时候坐标系  X轴在三点钟方向 Y轴在六点钟方向        canvas.restore();        //箭头和线的颜色换成红色        mPaint.setColor(Color.RED);        //现在开始画箭头底下的线        canvas.drawLine(0, 0, 0, -radius + dp2px(3), mPaint);        Path path = new Path();        //画箭头        path.moveTo(-dp2px(3), -radius);//三角形左下角顶点        path.lineTo(dp2px(3), -radius);//三角形右下角顶点        path.lineTo(0, -radius - dp2px(3)); //顶点        path.close();        canvas.drawPath(path, mPaint);        //写文字        String MyText = "MyCanvasClock";        float MyTextSize = mTextPaint.measureText(MyText);        canvas.drawText(MyText, -MyTextSize / 2, dp2px(30), mTextPaint);    }    public int dp2px(int dp) {        return (int) (dp * mContext.getResources().getDisplayMetrics().density + 0.5f);    }}


九.做个类似于芝麻信用分的实践

//步骤在代码中写(除了画等级分数之类,这个简单,可以参考上面的画钟)

public class MyView extends View {    //外围圆    private Paint outSideCirlePaint = new Paint();    //去掉下面的120    private Paint arc120Paint = new Paint();    //画大刻度的画笔    private Paint BigScalePaint = new Paint();    //画小刻度的画笔    private Paint smallScalePaint = new Paint();    //画中间的分数和信用等级    private Paint textPaint = new Paint();    //画进度条    private Paint processPaintBackGroud = new Paint();    private Paint processPaint = new Paint();    //画图片    private Paint bitmapPaint = new Paint();    private int viewWidth;    private int viewHeight;    private Context mContext;    private int outSideCriclePaintWidth;    private int innerSideCriclePaintWidth;    private int mCenterX;    private int mCenterY;    private int mRadius;    private String creditRand;    private float  creditScore;    private Bitmap bitmapArrow;    private int mInnerSideRadius;    private float totalRotateAngle;    private boolean rotating = false;    private float rotateAngle;    private float currentAngle;    public interface setRotateAnlgleListener {        void setRotateAngle(int rotateAngle);    }    public MyView(Context context) {        super(context);        this.mContext = context;        init();    }    public MyView(Context context, AttributeSet attrs) {        super(context, attrs);        this.mContext = context;        init();    }    public MyView(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        this.mContext = context;        init();    }    private void init() {        initData();        initPaint();    }    private void initData() {        //最外面圆画笔的宽度        outSideCriclePaintWidth = CommonUtils.Dp2Px(mContext, 10);        innerSideCriclePaintWidth = CommonUtils.Dp2Px(mContext, 5);        //信用等级        creditRand = "信用等级";        //信用分数        creditScore = 350;    }    private void initPaint() {        //在外面的大圆画笔的设置        outSideCirlePaint.setAntiAlias(true);        outSideCirlePaint.setColor(Color.parseColor("#E0E0E0"));        outSideCirlePaint.setStrokeWidth(outSideCriclePaintWidth);        outSideCirlePaint.setStyle(Paint.Style.STROKE);        outSideCirlePaint.setAlpha(50);        //设置圆正下方152度去掉圆弧的画笔        arc120Paint.setAntiAlias(true);        arc120Paint.setColor(Color.parseColor("#9393FF"));        arc120Paint.setStyle(Paint.Style.FILL_AND_STROKE);        //初始化画大刻度的画笔        BigScalePaint.setAntiAlias(true);        BigScalePaint.setColor(Color.parseColor("#000000"));        BigScalePaint.setStyle(Paint.Style.STROKE);        BigScalePaint.setStrokeWidth(CommonUtils.Dp2Px(mContext, 2));        //初始化画小刻度的画笔        smallScalePaint.setAntiAlias(true);        smallScalePaint.setColor(Color.parseColor("#000000"));        smallScalePaint.setStyle(Paint.Style.STROKE);        smallScalePaint.setStrokeWidth(CommonUtils.Dp2Px(mContext, 1));        //初始化画字的画笔        textPaint.setAntiAlias(true);        textPaint.setColor(Color.parseColor("#ffffff"));        textPaint.setStyle(Paint.Style.STROKE);        textPaint.setTextSize(CommonUtils.Dp2Px(mContext, 20));        //进度条的画笔        processPaint.setAntiAlias(true);        processPaint.setColor(Color.parseColor("#00ff00"));        processPaint.setStyle(Paint.Style.STROKE);        processPaint.setStrokeWidth(innerSideCriclePaintWidth);        processPaintBackGroud.setAntiAlias(true);        processPaintBackGroud.setColor(Color.parseColor("#4DFFFF"));        processPaintBackGroud.setStyle(Paint.Style.STROKE);        processPaintBackGroud.setStrokeWidth(innerSideCriclePaintWidth);        //图片        bitmapPaint.setAntiAlias(true);    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        //获取中心        mCenterX = getWidth() / 2;        mCenterY = getHeight() / 2;        mRadius = mCenterX - outSideCriclePaintWidth / 2;        //1.画出最外面的大圆        canvas.drawCircle(mCenterX, mCenterY, mRadius, outSideCirlePaint);        //2.把中心的移到view的中心        canvas.translate(mCenterX, mCenterY);        //3.然后画刻度 大的  小的(总共30个空格,240度,一格是八度,6格是一个大刻度)        //从右画到左        //(1)先把canvas先逆时针转 60        for (int i = 0; i < 31; i++) {            canvas.save();            canvas.rotate(-(60 + i * 8), 0, 0);            if (0 == i % 6) {                //6个空格画个大刻度                canvas.drawLine(0, mCenterX, 0, mRadius - CommonUtils.Dp2Px(mContext, 10), BigScalePaint);            } else {                //画个小刻度                canvas.drawLine(0, mCenterX, 0, mRadius - CommonUtils.Dp2Px(mContext, 5), smallScalePaint);            }            //还原到最开始的地方            //也就是坐标中心在view中心的时候  x  y 水平竖直            canvas.restore();        }        //6.画信用等级        //7.画进度条//此时坐标轴的原点就在view中心        mInnerSideRadius = mCenterX - CommonUtils.Dp2Px(mContext, 20);        //进度条的背景        canvas.drawCircle(0, 0, mInnerSideRadius, processPaintBackGroud);        //进度条        RectF rectF = new RectF(-mInnerSideRadius, -mInnerSideRadius, mInnerSideRadius, mInnerSideRadius);        //-210 startAngle  120 sweepAngle        canvas.drawArc(rectF, -210, currentAngle, false, processPaint);        //8.去掉正下方的240度的圆弧        //现在view的中心的是(0,0)        clear120Arc(0, 0, canvas);        canvas.save();        //9.画出图片        bitmapArrow = BitmapFactory.decodeResource(getResources(), R.drawable.arrow);        canvas.rotate(-30+currentAngle);        Matrix matrix = new Matrix();        int bitmapWidth = bitmapArrow.getWidth();        int bitmapHeight = bitmapArrow.getHeight();        //这时候坐标系  已经逆时针偏转30度        matrix.preTranslate(-mInnerSideRadius - bitmapWidth * 3 / 8, -bitmapHeight / 2);        canvas.drawBitmap(bitmapArrow, matrix, bitmapPaint);        canvas.restore();        //4.画中间的字        float creditTextWidth = textPaint.measureText(creditRand);        canvas.drawText(creditRand, -creditTextWidth / 2, CommonUtils.Dp2Px(mContext, 50), textPaint);        //5.画中间的分数        float creditScoreWidth = textPaint.measureText(String.valueOf((int)creditScore));        canvas.drawText(String.valueOf((int)creditScore), -creditScoreWidth / 2, CommonUtils.Dp2Px(mContext, 30), textPaint);    }    /**     * 清除下面的120度的圆弧     */    private void clear120Arc(int screenWithCenter, int screenHeighWidth, Canvas canvas) {        Point pointLeftBotton = new Point();        //设置左下角的点        pointLeftBotton.set(screenWithCenter - viewWidth / 2, screenHeighWidth + (int) ((viewWidth / 2) * Math.tan((Math.PI / 180) * 30)));        Point pointRightBotton = new Point();        //设置右下角的点        pointRightBotton.set(screenWithCenter + viewWidth / 2, screenHeighWidth + (int) ((viewWidth / 2) * Math.tan((Math.PI / 180) * 30)));        Path path = new Path();//        path.reset();        path.moveTo(screenWithCenter, screenHeighWidth);        path.lineTo(pointLeftBotton.x, pointLeftBotton.y);        path.lineTo(pointLeftBotton.x, screenHeighWidth + viewHeight / 2);        path.lineTo(pointRightBotton.x, screenHeighWidth + viewHeight / 2);        path.lineTo(pointRightBotton.x, pointRightBotton.y);        path.close();        System.out.println("xcqw screentWidthCenter-" + screenWithCenter + "-screenHeighWidth-" + screenHeighWidth);        System.out.println("xcqw pointLeftBotton-" + pointLeftBotton.x + "-pointLeftBotton.y-" + pointLeftBotton.y);        System.out.println("xcqw pointRightBotton-" + pointRightBotton.x + "-pointRightBotton.y-" + pointRightBotton.y);        canvas.drawPath(path, arc120Paint);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        //获取view的宽度,高度        viewWidth = w;        viewHeight = h;        System.out.println("xcqw viewWidth-" + viewWidth + "-viewHeight-" + viewHeight);    }    public void setRotateAngle(int outcreditScore) {        System.out.println("xcqw setRotateAngle");//                if ( creditScore <= 350 ) {//                    totalRotateAngle = 0f;//                } else if ( creditScore <= 550 ) {//                    totalRotateAngle = ( creditScore - 150 ) * 80 / 400f ;//                } else if ( creditScore <= 700 ) {//                    totalRotateAngle = ( creditScore - 550 ) * 120 / 150f + 80 ;//                } else if ( creditScore <= 950 ) {//                    totalRotateAngle = ( creditScore - 700 ) * 40 / 250f + 200;//                } else {//                    totalRotateAngle = 240f ;//                }        if (outcreditScore <= 350) {            totalRotateAngle = 0f;        } else if (outcreditScore <= 950) {            //总共240度  量程是350- 950分            totalRotateAngle = (outcreditScore - 350)/(600 / 240);        } else {            totalRotateAngle = 240f;        }        rotateAngle = totalRotateAngle / 60;        currentAngle = 0;        new Thread(new Runnable() {            @Override            public void run() {                rotating = true;                while (rotating) {                    //箭头正在旋转                    currentAngle += rotateAngle;                    creditScore = (600/240)*currentAngle+350;                    SystemClock.sleep(50);                    if (currentAngle >= totalRotateAngle) {                        currentAngle = totalRotateAngle;                        rotating = false;                    }                    if (currentAngle >= 0 && currentAngle < 91) {                        creditRand = "信用较差";                    } else if (currentAngle > 90 && currentAngle < 151) {                        creditRand = "信用良好";                    } else if (currentAngle > 150) {                        creditRand = "信用优秀";                    }                    postInvalidate();                }            }        }).start();    }}
源码在这里


0 0
原创粉丝点击