自定义View (三)Graphics2D 的基本使用

时间:2021-12-27 11:15:47

Graphics2D 的基本使用

1、 Point & PointF

两者都表示点,实现了Parcelable 接口,支持序列化和反序列化 ,定义了连个成员变量,x,y坐标 ,这个类比较简单,就不记录了

2、 Rect & RectF

定义的是一个矩形结构,理解其中定义的4个坐标点九OK了,分别是
left、top、right、bottom

3、Bitmap & BitmapDrawable

位图 ,要了解的是其中的几个方法

  • public static Bitmap decodeStream(InputStream is) 从输入流读取图片数据并转换成Bitmap对象
  • public static Bitmap decodeResource(Resource resent id) 从资源中获取并且转换成Bitmap对象
  • public static Bitmap decodeByteArray(byte[] data, int offset, int length) 从字节数组中读取并且转换
  • public static Bitmap decodeFile(String path) 读取文件并且转换成Bitmap对象
  • 也可以使用createBitmap() 自定义大小和格式 ,
  • 其他的要知道的方法应该是释放图片资源,recycle()

4、Canvas & Paint

4.1 Paint

画笔类 ,方法参数未写(只是方便查找)

  1. 与颜色相关的方法
方法名 作用
setColor() 设置颜色
setAlpha() 设置透明度
setARGB() 指定透明度并且给定三原色来定义一种颜色

2. 文本相关的方法

方法名 作用
setTextSize() 设置字体大小
setTextAlign() 设置文本的对齐方式
setTextSkewX() 设置文本的倾斜程度
setUnderLineText() 给文本添加下划线
setFakeBoldText() 设置文本粗体样式
setStrikeThruText() 给文本添加删除线

3. 图形样式相关的类

方法名 作用
setStyle() 设置绘制的图形的样式
setStrokeJoin() 当绘图的样式是STROKE的时候 该方法用于指定拐角的样式
setStrokeCap() 设置落笔时的样式,控制我们的画笔在离开画板时留下的最后一点图形
setStrokeWidth() 设置线条的宽度
//样式的可选值
public static enum Style{
    FILL //实心样式
    FILL_AND_STROKE //实心/空心样式
    STROKE// 空心样式
}
//拐角的样式
public static enum Jian{
    BEVEL
    MITER
    ROUND
}

图片来源于《Android自定义组件开发详解》
自定义View (三)Graphics2D 的基本使用

// 落笔时的样式
public static enum Cap{
    BUTT
    ROUND
    SQUARE
}

同上
自定义View (三)Graphics2D 的基本使用

4.2 Canvas

此类中封装了大量的绘图的方法,一般情况下将会对这几方面进行绘图

  1. 位图
  2. 线
  3. 矩形
  4. 路径
  5. 文字

4.2.1 位图

首先绘制位图的方法:

方法名 作用
drawBitmap(Bitmap bitmap,float left,float top ,Paint paint) 最简单的方法,将bitmap绘制在画布上,指定大小和位置,不进行任何的缩放,除非进行位图运算,不然paint直接传null
drawBitmap(Bitmap bitmap,Rect src, Rect dust, Paint paint). drawBitmap(Bitmap bitmap,Rect src, RectF dust, Paint paint) 都是从Bitmap中取出类一个区域src ,并绘制到canvas的dst处 ,src 和dst的大小与比例关系影响最重的效果
 /** 这是一个例子: * 绘制两张图片,一张按照原大小绘制,另一张放大3陪 */
    private fun drawBitmap() {
        var createBitmap: Bitmap = Bitmap.createBitmap(500, 800, Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(createBitmap)
        val bitmap: Bitmap = BitmapFactory.decodeResource(resources, R.mipmap.ic_launcher)
        //原大小绘制
        mCanvas?.drawBitmap(bitmap, 0F, 0F, null)
        //对图片进行缩放
        val width: Int = createBitmap.width
        val height: Int = createBitmap.height
        //从图中取出的src
        val mRect: Rect = Rect(0, 0, width, height)
        //绘制到canvas中dst
        val mRectD: Rect = Rect(0, height, width.times(3), height.times(3).plus(height))
        mCanvas?.drawBitmap(createBitmap, mRect, mRectD, null)

        mImage?.setImageBitmap(createBitmap)
    }

4.2.2 点

她的大小 取决于setStroketWidth()方法的参数 值愈大 点雨大
绘制点的方法:

方法名 作用
drawPoint(float x, float y,Paint paint) 在(x,y)处绘制一个点
drawPoints(float[] its,Paint paint) 设置方法的参数pts是一个数组,从下表0开始每两个数确定一个点 连续绘制,多余的丢弃
drawPoints(float[] its ,int offset, int count ,Paint paint) 从指定的位置去出响应的数量,每两个画点
 /** * 画点 * kotlin 中的方法有可能和上边不一致 但是是一样的 */
    private fun drawPoint() {
        val bitmap: Bitmap = Bitmap.createBitmap(200, 800, Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(bitmap)
        mPaint = Paint()
        mPaint?.color = Color.RED
        mPaint?.strokeWidth = 40F
        mCanvas?.drawPoint(0F, 150F, mPaint)
        mPaint?.color = Color.BLUE
        mCanvas?.drawPoint(300F, 0F, mPaint)
        mImage?.setImageBitmap(bitmap)

    }

4.2.3 线

两个点确定一条线,当然画线的时候就需要点
方法:

方法名 作用
drawLine(float startX, float startY,,float stopX,float stopY Paint paint) (startX,startY) (stopX,stopY) 两组点绘制一条线
drawLines(float[] its,Paint paint) 设置方法的参数pts是一个数组,从下表0开始每4个数画线 连续绘制,多余的丢弃
drawLines(float[] its ,int offset, int count ,Paint paint) 从指定的位置去出响应的数量,每4个画线
/** * 画线 */
    private fun drawLine() {

        val bitmap:Bitmap = Bitmap.createBitmap(500,800,Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(bitmap)
        mPaint = Paint()
        mPaint?.color = Color.RED
        mPaint?.strokeWidth = 1F
        val offsetDy = 50
        for (i in 0..5){
            mCanvas?.drawLine(10F, offsetDy.times(i).toFloat(),300F, offsetDy.times(i).toFloat(),mPaint)
        }
    }

4.2.4 矩形

包含了直角举行和圆角矩形
绘制直角矩形的方法

方法名 作用
drawRect() 有三个重载的方法

绘制圆角的方法

方法名 作用
drawRoundRect() 有二个重载的方法
这个没有下Demo 后面找时间再说

4.2.5 圆

在图形分类的时候,将圆,椭圆,扇形,弧线,都归到圆中,
椭圆的大小是他的外切矩形来决定的

4.2.5.1绘制椭圆的方法

方法名 作用
drawOval(float left ,float top,float right,float bottom,Paint paint) 绘制椭圆
drawOval(RectF oval ,Paint paint) 绘制椭圆
drawCircle(float cx, float cy,float radius,Paint paint) (cx,cy)圆心,radius 半径

4.2.5.2 扇形、弧

弧线是椭圆上的一点,而扇形测试闭合的弧线
(同上)
自定义View (三)Graphics2D 的基本使用
方法

方法名 作用
1、drawArc(RectF oval,float startAngle ,float sweepAngle,boolean useCenter,Paint paint) 2、drawArc(float left, float top, float right, float bottom ,float startAngle ,float sweepAngle,boolean useCenter,Paint paint) startAngle表示其实角度,sweepAngle扇形或弧线所占的角度,正数表示顺时针,反之表示捏是真,useCenter 是否使用中心点,true 扇形,false 弧线

4.2.5.3 Path 路径

这个在自定义view中相对重要,他一般用于绘制复杂图形,
具体的功能可以归纳为

  1. 往path中添加线
  2. 往path中添加矩形、圆、弧
  3. 往path中添加曲线和贝塞尔曲线
  4. 将Path中的图形进行运算

path可以绘制出很复杂的图形
方法

方法名 作用
moveTo(float x,float y) 将画笔移动到(x,y)点
rMoveTo(float dx,float dy) 将画笔移动到一个新点,但是新点偏移是(dx,dy),新点的坐标就是(x + dx,y + dy)
lineTo(x,y) 将画笔移动到x,y位置上
rLineTo(dx,dy) 偏移,移动
close() 将第一个点和最后一个点连接

画一个五角星的Demo

/** * 画五角星 */
    private fun drawFivePointedStar() {
        val bitmap: Bitmap = Bitmap.createBitmap(500, 800, Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(bitmap)
        mPaint = Paint()
        mPaint?.style = Paint.Style.STROKE
        val mPath: Path = Path()
        mPath.moveTo(0F, 150F) //将画笔移动到该点
        mPath.rLineTo(300F, 0F) //在rLineTo 的时候 是将画笔拖到下一个新的点 这个点的位置坐标是(原来的点 + 新的点,原来的点 + 新的点)
        // (0F + 300F,150F + 0F)----> (300F,150F)
        mPath.rLineTo(-300F, 150F)
        mPath.rLineTo(150F, -300F)
        mPath.rLineTo(150F, 300F)
        mPath.close() //将最后一点和第一点连接在一起形成闭合区域
        mCanvas?.drawPath(mPath, mPaint)
        mImage?.setImageBitmap(bitmap)

    }

添加矩形、圆等方法

方法名 作用
addRect() 添加矩形
addRect(float left, float top, float right, float bottom,Path.Directin dir) 添加矩形
addRoundRect(RectF rect,float[] radio,Path.Direction dir) 添加圆角矩形
addRoundRect(RectF rect,float x, float y,Path.Direction dir) 添加圆角矩形
addRoundRect(float left, float top, float right, float bottom,float[] radio,Path.Direction dir) 添加圆角矩形 可以定义四个角的不同的弧度
addOval(RectF rect,Path.Direction dir) 同下
addOval(float left, float top, float right, float bottom,Path.Direction dir) 添加一个椭圆
addCircle(float x, float y, float radius,Path.Direction dir) 添加一个圆
addArc(RectF rect,float startAngle,float sweepAngle)
addArc(float left, float top, float right, float bottom,float startAngle,float sweepAngle) 添加一段弧线


弧线包括 曲线和贝塞尔曲线
贝塞尔曲线简单例子

自定义View (三)Graphics2D 的基本使用

这里又一个二阶贝塞尔曲线的例子

 /** * 绘制二级贝塞尔曲线 * 1 两个点 起点 终点 * 2 三个点 起点 终点 控制点 * 3 四个点 起点 终点 两个控制点 */
    private fun drawTwoBessel() {
        val bitmap: Bitmap = Bitmap.createBitmap(800, 800, Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(bitmap)
        mPaint = Paint()
        mPaint?.style = Paint.Style.STROKE
        val mPath = Path()
        mPath.moveTo(100F, 100F)
        mPath.quadTo(200F, 10F, 300F, 300F) //x1 y1 是控制点 ,x2 y2 是终点
        mCanvas?.drawPath(mPath, mPaint)
        mPaint?.strokeWidth = 4F
        mPaint?.color = Color.RED
        val mFloat: FloatArray = floatArrayOf(100F, 100F, 200F, 10F, 300F, 300F)
        mCanvas?.drawPoints(mFloat, mPaint) //将上述的几个点给绘制出来了
        mImage?.setImageBitmap(bitmap)
    }

4.2.6 图形的运算

path有一个静态类 Op 定义了5种运算规则

规则 说明
Path.Op.DIFFERENCE 差集,图形A减去图形B重叠的区域后A余下的区域
Path.Op.INTERSECT 交集,图形A和B的重叠区域
Path.Op.REVERSE_DIFFERENCE 反差集,图形B减去与A重叠的区域后B余下的区域
Path.Op.UNION 并集,包含了A与B的所有区域
Path.Op.XOR 补集,A和B的所有区域减去他们重叠区域后余下的区域

自定义View (三)Graphics2D 的基本使用
自定义View (三)Graphics2D 的基本使用

4.2.7 绘制文字

方法 说明
drawText() 绘制文字
drawTextOnPath() 沿着Path的路径绘制文字
 /** * 画文字 */
    private fun drawText() {
        val mBitmap: Bitmap = Bitmap.createBitmap(500, 800, Bitmap.Config.ARGB_8888)
        mCanvas = Canvas(mBitmap)
        mPaint = Paint()
        mPaint?.color = Color.RED
        mPaint?.isAntiAlias = true
        mPaint?.textSize = 30F
        mPaint?.style = Paint.Style.FILL
        val mPath = Path()
        mPath.moveTo(10F, 200F)
        mPath.quadTo(100F, 100F, 300F, 300F)
        mCanvas?.drawTextOnPath("图形A减去图形B 重叠的区域后剩余的区域", mPath, 15F, 15F, mPaint)
        mPaint?.style = Paint.Style.STROKE
        mCanvas?.drawPath(mPath, mPaint)
        mImage?.setImageBitmap(mBitmap)

    }

这就是一个Graphics2D 的静态绘制,接下来学习实现动态效果