android 自定义控件画板 PaintView
该代码实现了一个安卓手绘板控件PaintView,支持实时绘制、路径记录与清除功能。通过Touch事件捕捉手势,使用Path和Paint绘制平滑轨迹,采用贝塞尔曲线实现流畅笔触。用户可自由绘画,支持多条轨迹保存,并可通过clear()方法清空画板。
点击查看代码
package com.run.treadmill
import android.content.Context
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
//笔记 起点和路径
data class Stroke(val path:Path,val paint: Paint)
class PaintView :View {
constructor(context: Context) : super(context){
init(null)
}
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs){
init(attrs)
}
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
context,
attrs,
defStyleAttr){
init(attrs)
}
//轨迹集合
private val strokeList=mutableListOf<Stroke>()
private val currentPath=Path()
private val drawPaint=Paint()
//触摸临时坐标
private var lastx=0f
private var lasty=0f
private fun init(attrs: AttributeSet?){
resetNormalPaint()
}
fun resetNormalPaint(){
//1.画笔实例化
drawPaint.apply {
isAntiAlias=true
style= Paint.Style.STROKE
strokeWidth=8f
color=Color.BLACK
strokeCap=Paint.Cap.ROUND
}
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec),MeasureSpec.getSize(heightMeasureSpec))
}
override fun onDraw(canvas: Canvas?) {
super.onDraw(canvas)
//2.画出所有的轨迹
strokeList.forEach {
canvas?.drawPath(it.path,it.paint)
}
//3.画出正在画的轨迹
canvas?.drawPath(currentPath,drawPaint)
}
override fun onTouchEvent(event: MotionEvent): Boolean {
val x=event.x
val y=event.y
//边界
val inBounds= x >= 0 && x<= width && y >0 && y <= height
if (!inBounds) return true
when(event.action){
//手指按下开启新的笔迹
MotionEvent.ACTION_DOWN -> {
currentPath.reset()
currentPath.moveTo(x,y)
lastx=x
lasty=y
}
//手指滑动,连续画线 贝塞尔曲线的控制点取两点中点
MotionEvent.ACTION_MOVE -> {
currentPath.quadTo(lastx,lasty,(x+lastx)/2,(y+lasty)/2)
lastx=x
lasty=y
}
//手指抬起,保存当前笔迹到集合
MotionEvent.ACTION_UP -> {
strokeList.add(Stroke(Path(currentPath),drawPaint))
currentPath.reset()
}
}
invalidate()//刷新界面
// return super.onTouchEvent(event)
return true
}
//清空画板
fun clear(){
strokeList.clear()
currentPath.reset()
invalidate()
}
//撤回上一笔
fun undo(){
if(strokeList.isNotEmpty()){
strokeList.removeLast()
invalidate()
}
}
//画笔颜色
fun setPaintColor(color:Int){
drawPaint.color=color
}
//橡皮擦
fun useEraser(){
drawPaint.color= Color.WHITE
drawPaint.strokeWidth=25f
}
fun usePen(){
resetNormalPaint()
}
}

浙公网安备 33010602011771号