直接上代码了:
/** * *@ClassName:GraphicsView *@author:WYL *@Date:2022/9/29 */ class GraphicsView : View { private var mWidth = 0 private var mHeight = 0 /** * 圆的半径 */ private var radius = 80f //默认的点 private val graphicsPoints = mutableListOf<GraphicsPoint>() //选中的点 private val checkGraphicsPoints = mutableListOf<GraphicsPoint>() private val mPaint: Paint by lazy { Paint(Paint.ANTI_ALIAS_FLAG).apply { isAntiAlias = true style = Paint.Style.FILL isDither = true } } private val linePaint: Paint by lazy { Paint(Paint.ANTI_ALIAS_FLAG).apply { isAntiAlias = true style = Paint.Style.FILL isDither = true strokeWidth = 10f mPaint.pathEffect = CornerPathEffect(10f) color = Color.parseColor("#FF575E") strokeCap = Paint.Cap.ROUND } } constructor(context: Context?) : this(context, null) constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( context, attrs, defStyleAttr ) { init() } private fun init() { graphicsPoints.clear() graphicsPoints.add(GraphicsPoint(1)) graphicsPoints.add(GraphicsPoint(2)) graphicsPoints.add(GraphicsPoint(3)) graphicsPoints.add(GraphicsPoint(4)) graphicsPoints.add(GraphicsPoint(5)) graphicsPoints.add(GraphicsPoint(6)) graphicsPoints.add(GraphicsPoint(7)) graphicsPoints.add(GraphicsPoint(8)) graphicsPoints.add(GraphicsPoint(9)) } override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { val width = MeasureSpec.getSize(widthMeasureSpec) val height = MeasureSpec.getSize(heightMeasureSpec) mWidth = Math.min(width, height) mHeight = mWidth setMeasuredDimension(mWidth, mHeight) } /** * 选中颜色 */ private val selectColor = Color.parseColor("#FF575E") private val selectColorTransparent = Color.parseColor("#32FF575E") private val unselectColor = Color.parseColor("#BCC6CE") override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) val averageWidth = mWidth / 3f val averageHeight = mHeight / 3f for (i in 0 until 3) { for (j in 0 until 3) { graphicsPoints[i * 3 + j].apply { x = (averageWidth * (j + 1)) - averageWidth / 2f y = (averageHeight * (i + 1)) - averageHeight / 2f } } } var startX = 0f var startY = 0f var stopX = 0f var stopY = 0f checkGraphicsPoints.forEachIndexed { index, it -> if (index > 0) { stopX = it.x stopY = it.y canvas?.drawLine(startX, startY, stopX, stopY, linePaint) startX = stopX startY = stopY } else { startX = it.x startY = it.y } } if (continueJudge) { canvas?.drawLine(startX, startY, currentX, currentY, linePaint) } graphicsPoints.forEach { if (it.isSelect) { mPaint.color = selectColorTransparent canvas?.drawCircle(it.x, it.y, radius, mPaint) mPaint.color = selectColor canvas?.drawCircle(it.x, it.y, radius/3, mPaint) } else { mPaint.color = unselectColor canvas?.drawCircle(it.x, it.y, radius/3, mPaint) } } } /** * 判断滑动时是否去判断 */ private var continueJudge = false private var currentX = 0f private var currentY = 0f override fun onTouchEvent(event: MotionEvent): Boolean { when (event.action) { MotionEvent.ACTION_DOWN -> { graphicsPoints.forEach { if (judgeCircle(it, event.x, event.y)) { //Log.e(GraphicsView::class.java.canonicalName, "在圆点里面!!!!!!!!!!!!!") continueJudge = true it.isSelect = true checkGraphicsPoints.add(it) currentX = event.x currentY = event.y invalidate() return@forEach } } } MotionEvent.ACTION_MOVE -> { if (continueJudge) { currentX = event.x currentY = event.y invalidate() } graphicsPoints.forEach { if (judgeCircle(it, event.x, event.y) && !it.isSelect) { //Log.e(GraphicsView::class.java.canonicalName, "在圆点里面!!!!!!!!!!!!!") it.isSelect = true checkGraphicsPoints.add(it) if (!continueJudge) { currentX = event.x currentY = event.y continueJudge = true } invalidate() return@forEach } } } MotionEvent.ACTION_UP -> { val selects = checkGraphicsPoints.filter { it.isSelect } if(selects.isNotEmpty()){ val subString = StringBuffer() selects.forEach { subString.append("${it.type}") } //ToastUtils.showShort(subString) onResultListener?.onResult(subString.toString()) } continueJudge = false checkGraphicsPoints.clear() graphicsPoints.forEach { it.isSelect = false } invalidate() } } return true } /** * 判断触点是否在圆里面 */ fun judgeCircle(p: GraphicsPoint, m_x: Float, m_y: Float): Boolean { val c = Math.pow( Math.pow( p.x.toDouble() - m_x.toDouble(), 2.0 ) + Math.pow(p.y.toDouble() - m_y.toDouble(), 2.0), 0.5 ) return (c < radius) } inner class GraphicsPoint { var x = 0f var y = 0f var type: Int = -1 var isSelect = false constructor(x: Float, y: Float, type: Int) { this.x = x this.y = y this.type = type } constructor(type: Int) { this.type = type } } var onResultListener:OnResultListener? = null interface OnResultListener{ fun onResult(password:String) } }
效果图:
版权声明:本文为z18374453733原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。