一:图形的位置和尺寸测量

文章介绍了Android中的Canvas、Paint、Path以及Direction在视图绘制中的作用,包括如何使用它们绘制线、圆、图形相交及填充类型。着重讲解了Path的使用和Direction对图形相交效果的影响。
摘要由CSDN通过智能技术生成

绘制的基本要素:

onDraw(Canvas):是用来重写的

Canvas:实际执行绘制的

Paint:调整粗细和颜色等

坐标系:以屏幕左上角为原点,向右、向下为正向数值的坐标系

尺寸单位:在绘制过程中所有的尺寸单位都是px,像素,在绘制阶段是直接跟屏幕打交道的

举例,我们画一条线

package com.example.viewtest.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View

class TestView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawLine(100f, 100f, 300f, 300f, paint)
    }
}

画个圆

package com.example.viewtest.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.util.AttributeSet
import android.view.View
import com.example.viewtest.ext.dp

class TestView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)

        canvas.drawCircle(width / 2f, height / 2f, 100.dp, paint)
    }
}

接下来讲Path,path不是用来绘制路径的,绘制路径只是其中一个功能而已,他是用来绘制图形的

使用Path绘制一个圆

package com.example.viewtest.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import com.example.viewtest.ext.dp

class TestView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    private val path = Path()

    // 在尺寸发生改变的时候,初始化 path
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        path.reset()
        // 最后一个参数:Direction,CW:顺时针,CCW:逆时针
        path.addCircle(width / 2f, height / 2f, 100.dp, Path.Direction.CW)
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
//        canvas.drawLine(100f, 100f, 300f, 300f, paint)
//
//        canvas.drawCircle(width / 2f, height / 2f, 100.dp, paint)

        canvas.drawPath(path, paint)
    }
}

这里主要讲一下Direction,Direction主要是用来处理两个图形相交处的样子,通过Direction的配合使用,可以使图形相交地方之处实现实心还是镂空的效果,这里有一个标准

如果要确定一个点是在内部还是外部,那么就从这个点像任意方向发送一条射线,这条线遇到左旋(逆时针)路径就+1,右旋路径就-1,最终结果无论正负,只要不为0,那么这就是一个在内部的点

除此之外,一般使用path.fillType属性,他的默认值是Path.FillType.WINDING,使用path.fillType是另一套计算方式,也就是说不管左旋还是右旋,一个点只记录和path的相交次数,奇数为内部,偶数为外部

镂空效果直接设置为 path.fillType = Path.FillType.EVEN_ODD

举个例子,一个圆和一个方相交

package com.example.viewtest.view

import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.View
import com.example.viewtest.ext.dp

class TestView(context: Context, attrs: AttributeSet) : View(context, attrs) {

    private val paint = Paint(Paint.ANTI_ALIAS_FLAG)

    private val path = Path()

    // 在尺寸发生改变的时候,初始化 path
    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        path.reset()
        // 最后一个参数:Direction,CW:顺时针,CCW:逆时针
        path.addCircle(width / 2f, height / 2f, 100.dp, Path.Direction.CW)

        path.addRect(width / 2f - 100.dp, height / 2f, width / 2f + 100.dp, height / 2f + 2 * 100.dp, Path.Direction.CCW)
        // 第二个参数的作用是是否要自动闭合
        pathMeasure = PathMeasure(path, false)
        
        pathMeasure.length
        // 给定一个长度,会返回当前长度所处位置的切点,也就是正弦值
        pathMeasure.getPosTan()

        path.fillType = Path.FillType.EVEN_ODD
    }

    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
//        canvas.drawLine(100f, 100f, 300f, 300f, paint)
//
//        canvas.drawCircle(width / 2f, height / 2f, 100.dp, paint)

        canvas.drawPath(path, paint)
    }
}

pathMeasure = PathMeasure(path, false)

第二个参数的作用是是否要自动闭合,如果一个图形假设是个半圆,那么测量的就是这个半圆的长度,如果是true就是半圆+起始点连接线的长度

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值