Android自定义View学习三---图形绘制

Posted winfredzen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义View学习三---图形绘制相关的知识,希望对你有一定的参考价值。

android自定义View学习三

内容来自:安卓自定义View进阶-Canvas之绘制图形

Paint

Paint相当于是画笔,某些方面与ios绘制还是很相似的

设置画笔样式,有三种模式

STROKE                //描边
FILL                  //填充
FILL_AND_STROKE       //描边加填充

Canvas之绘制图形

Canvas的常用操作速查表

操作类型相关API备注
绘制颜色drawColor, drawRGB, drawARGB使用单一颜色填充整个画布
绘制基本形状drawPoint, drawPoints, drawLine, drawLines, drawRect, drawRoundRect, drawOval, drawCircle, drawArc依次为 点、线、矩形、圆角矩形、椭圆、圆、圆弧
绘制图片drawBitmap, drawPicture绘制位图和图片
绘制文本drawText, drawPosText, drawTextOnPath依次为 绘制文字、绘制文字时指定每个文字位置、根据路径绘制文字
绘制路径drawPath绘制路径,绘制贝塞尔曲线时也需要用到该函数
顶点操作drawVertices, drawBitmapMesh通过对顶点操作可以使图像形变,drawVertices直接对画布作用、 drawBitmapMesh只对绘制的Bitmap作用
画布剪裁clipPath, clipRect设置画布的显示区域
画布快照save, restore, saveLayerXxx, restoreToCount, getSaveCount依次为 保存当前状态、 回滚到上一次保存的状态、 保存图层状态、 回滚到指定状态、 获取保存次数
画布变换translate, scale, rotate, skew依次为 位移、缩放、 旋转、错切
Matrix(矩阵)getMatrix, setMatrix, concat实际上画布的位移,缩放等操作的都是图像矩阵Matrix, 只不过Matrix比较难以理解和使用,故封装了一些常用的方法。

Canvas详解

绘制颜色

绘制颜色是填充整个画布,常用于绘制底色。

canvas.drawColor(Color.BLUE); //绘制蓝色

绘制点

绘制一个点

canvas.drawPoint(200, 200, mPaint); //在坐标(200,200)位置绘制一个点

绘制一组点,坐标由float数组指定

canvas.drawPoints(new float[] 500,500,500,600,500,700, mPaint);

绘制直线

绘制一条直线

canvas.drawLine(300,300,500,600,mPaint);    // 在坐标(300,300)(500,600)之间绘制一条直线
canvas.drawLines(new float[]               // 绘制一组线 每四数字(两个点的坐标)确定一条线
    100,200,200,200,
    100,300,200,300
,mPaint);

绘制矩形

绘制矩形,在android中一般采用左上角右上角的两个点的坐标

// 第一种,四个数值(矩形左上角和右下角两个点的坐标)来确定一个矩形
canvas.drawRect(100,100,800,400,mPaint);

// 第二种,矩形封装为Rect
Rect rect = new Rect(100,100,800,400);
canvas.drawRect(rect,mPaint);

// 第三种,矩形封装为RectF
RectF rectF = new RectF(100,100,800,400);
canvas.drawRect(rectF,mPaint);

Rect是int(整形)的,而RectF是float(单精度浮点型)的

绘制圆角矩形

// 第一种
RectF rectF = new RectF(100,100,800,400);
canvas.drawRoundRect(rectF,30,30,mPaint); 

// 第二种
canvas.drawRoundRect(100,100,800,400,30,30,mPaint);

drawRoundRect也可以绘制椭圆

绘制椭圆

// 第一种
RectF rectF = new RectF(100,100,800,400);
canvas.drawOval(rectF,mPaint);

// 第二种
canvas.drawOval(100,100,800,400,mPaint);

绘制圆

canvas.drawCircle(500,500,400,mPaint);  // 绘制一个圆心坐标在(500,500),半径为400 的圆。

绘制圆弧

方法如下:

// 第一种
public void drawArc(@NonNull RectF oval, float startAngle, float sweepAngle, boolean useCenter, @NonNull Paint paint)
    
// 第二种
public void drawArc(float left, float top, float right, float bottom, float startAngle,
            float sweepAngle, boolean useCenter, @NonNull Paint paint) 

相比于绘制椭圆,绘制圆弧还多了三个参数:

startAngle  // 开始角度
sweepAngle  // 扫过角度
useCenter   // 是否使用中心

如下的例子,绘制了一个起始角度为0度,扫过90度的圆弧,两者的区别就是是否使用了中心点

RectF rectF = new RectF(100,100,800,400);
// 绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF,mPaint);

// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF,0,90,false,mPaint);

//-------------------------------------

RectF rectF2 = new RectF(100,600,800,900);
// 绘制背景矩形
mPaint.setColor(Color.GRAY);
canvas.drawRect(rectF2,mPaint);

// 绘制圆弧
mPaint.setColor(Color.BLUE);
canvas.drawArc(rectF2,0,90,true,mPaint);

绘制饼状图

public class PieView extends View 
    // 颜色表 (注意: 此处定义颜色使用的是ARGB,带Alpha通道的)
    private int[] mColors = 0xFFCCFF00, 0xFF6495ED, 0xFFE32636, 0xFF800000, 0xFF808000, 0xFFFF8C69, 0xFF808080,
            0xFFE6B800, 0xFF7CFC00;
    // 饼状图初始绘制角度
    private float mStartAngle = 0;
    // 数据
    private ArrayList<PieData> mData;
    // 宽高
    private int mWidth, mHeight;
    // 画笔
    private Paint mPaint = new Paint();

    public PieView(Context context) 
        this(context, null);
    

    public PieView(Context context, AttributeSet attrs) 
        super(context, attrs);
        mPaint.setStyle(Paint.Style.FILL);
        mPaint.setAntiAlias(true);
    

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) 
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    

    @Override
    protected void onDraw(Canvas canvas) 
        super.onDraw(canvas);
        if (null == mData)
            return;
        float currentStartAngle = mStartAngle;                    // 当前起始角度
        canvas.translate(mWidth / 2, mHeight / 2);                // 将画布坐标原点移动到中心位置
        float r = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);  // 饼状图半径
        RectF rect = new RectF(-r, -r, r, r);                     // 饼状图绘制区域

        for (int i = 0; i < mData.size(); i++) 
            PieData pie = mData.get(i);
            mPaint.setColor(pie.getColor());
            canvas.drawArc(rect, currentStartAngle, pie.getAngle(), true, mPaint);
            currentStartAngle += pie.getAngle();
        

    

    // 设置起始角度
    public void setStartAngle(int mStartAngle) 
        this.mStartAngle = mStartAngle;
        invalidate();   // 刷新
    

    // 设置数据
    public void setData(ArrayList<PieData> mData) 
        this.mData = mData;
        initData(mData);
        invalidate();   // 刷新
    

    // 初始化数据
    private void initData(ArrayList<PieData> mData) 
        if (null == mData || mData.size() == 0)   // 数据有问题 直接返回
            return;

        float sumValue = 0;
        for (int i = 0; i < mData.size(); i++) 
            PieData pie = mData.get(i);

            sumValue += pie.getValue();       //计算数值和

            int j = i % mColors.length;       //设置颜色
            pie.setColor(mColors[j]);
        

        float sumAngle = 0;
        for (int i = 0; i < mData.size(); i++) 
            PieData pie = mData.get(i);

            float percentage = pie.getValue() / sumValue;   // 百分比
            float angle = percentage * 360;                 // 对应的角度

            pie.setPercentage(percentage);                  // 记录百分比
            pie.setAngle(angle);                            // 记录角度大小
            sumAngle += angle;

            Log.i("angle", "" + pie.getAngle());
        
    

  • 在更改了数据需要重绘界面时要调用invalidate()这个函数重新绘制
  • 将画布坐标原点移动到中心位置 canvas.translate(mWidth / 2, mHeight / 2);

以上是关于Android自定义View学习三---图形绘制的主要内容,如果未能解决你的问题,请参考以下文章

android自定义控件怎么用

android自定义文字绘制

Android自定义View学习五---图片文本绘制

自定义控件浅析

Android 自定义View之Draw过程(上)

Android自定义View画图的步骤及关于CanvasBitmapPaint的关系