实例 -自定义绘制滑动解锁

2022-07-22,,,,

效果图:

        

github地址:https://github.com/luofangli/draw_slideunclock

 

全部代码:

1:

 

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.constraintlayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".mainactivity">

<com.example.my.slideunlock
android:layout_width="200dp"
android:layout_height="200dp"
android:background="@color/design_default_color_primary"
app:layout_constraintbottom_tobottomof="parent"
app:layout_constraintend_toendof="parent"
app:layout_constrainthorizontal_bias="0.445"
app:layout_constraintstart_tostartof="parent"
app:layout_constrainttop_totopof="parent"
app:layout_constraintvertical_bias="0.499" />
</androidx.constraintlayout.widget.constraintlayout>


2:

 

 

package com.example.my

import android.graphics.color
import android.graphics.paint
import android.graphics.rect

class dot(x: float, y: float,radius:float,tag:int) {
//点的中心位置
val cx = x
val cy = y
//圆点的半径
val cradius = radius
//标记圆点的tag值
val ctag = tag
//是否已被点亮
var isorheightlight = false
//圆点的画笔
var paint = paint().apply {
style = paint.style.stroke
color = color.black
strokewidth = 5f
}
//圆点的矩形
var rect = rect((cx-cradius).toint(),(cy-cradius).toint(),
(cx+cradius).toint(),(cy+cradius).toint())
//设置圆点的画笔
fun setpaint(color:int){
paint.color = color
}
}


3:

package com.example.my

import android.content.context
import android.graphics.*
import android.util.attributeset
import android.util.log
import android.view.motionevent
import android.view.view
import androidx.core.graphics.contains

class slideunlock: view {
//存放9个点
private val dots = mutablelistof<dot>()
//存放被点亮的点
private val heightlightdots = mutablelistof<dot>()
//圆点的中心点的位置
private var cx = 0f
private var cy = 0f
private var radius = 0f
//记录线条的开始位置
private var startx = 0f
private var starty = 0f
//线条的末端位置
private var endx = 0f
private var endy = 0f
//没有连接两个点的线的路径
private var path = path()
//画线条的画笔
private val paintline:paint by lazy {
paint().apply {
style = paint.style.stroke
color = color.red
strokewidth = 5f
}
}
//画圆点的画笔
private val paint:paint by lazy {
paint().apply {
style = paint.style.stroke
strokewidth = 5f
color = color.black
}
}
//代码创建
constructor(context: context):super(context){}
//xml创建
constructor(context: context,attributeset: attributeset):super(context,attributeset){}

override fun onsizechanged(w: int, h: int, oldw: int, oldh: int) {
super.onsizechanged(w, h, oldw, oldh)
dot()
}

override fun ondraw(canvas: canvas?) {
super.ondraw(canvas)
drawdot(canvas)
canvas?.drawline(startx,starty,endx,endy,paintline)
drawlinein2dot(canvas)
}

override fun ontouchevent(event: motionevent?): boolean {
when(event?.action){
motionevent.action_down->{
//点亮圆点
heighlightdot(point(event.x.toint(), event.y.toint())).also {
if (it!=null){
heithliget(it)
//将其设置为已被点亮
it.isorheightlight = true

}
}
}
motionevent.action_move->{
//点亮圆点
heighlightdot(point(event.x.toint(), event.y.toint())).also {
if (it!=null){
//点亮点
heithliget(it)
//改变点是否已被加入被点亮数组的状态
it.isorheightlight = true
invalidate()
}
movepath(point(event.x.toint(),event.y.toint()))
}
}
motionevent.action_up->{
//恢复原状
originalstate()
}
}
return true
}
//在两个被点亮之间的画一条线
private fun drawlinein2dot(canvas: canvas?){
if (heightlightdots.size>1){
for (i in 0 until heightlightdots.size-1){
canvas?.drawline(heightlightdots[i].cx,heightlightdots[i].cy,
heightlightdots[i+1].cx,heightlightdots[i+1].cy,paintline)
}
}
}
//返回被触摸的点
private fun heighlightdot(point: point):dot?{
for (dot in dots){
if (dot.rect.contains(point)){
return dot
}
}
return null
}
//点亮点
private fun heithliget(dot: dot){
dot.setpaint(color.red)
//将被点亮的点记录
//判断是否已经被点亮了
if (dot.isorheightlight == false){
heightlightdots.add(dot)

}
invalidate()
}
//设置最后一个亮点移动的线的路径
private fun movepath(point: point){
val i =heightlightdots.size
log.v("lfl","最后路线")
startx = heightlightdots[i-1].cx
starty = heightlightdots[i-1].cy
endx = point.x.tofloat()
endy= point.y.tofloat()
invalidate()
}
//恢复原状
private fun originalstate(){
for (dot in heightlightdots){
dot.setpaint(color.black)
dot.isorheightlight = false
invalidate()
}
heightlightdots.clear()
//消去最后一根线
startx = 0f
starty = 0f
endx = 0f
endy = 0f
}
//将9个点准备好
private fun dot(){
radius = if (measuredheight>measuredwidth){
measuredwidth/14f
}else{
measuredheight/14f
}
for (row in 0..2){
for (clum in 0..2){
cx = (clum*4+3)*radius
cy = (row*4+3)*radius
dot(cx,cy,radius,row*10+clum).also {
dots.add(it)
}
}
}
}
//画9个点
private fun drawdot(canvas: canvas?){
for (dot in dots){
canvas?.drawcircle(dot.cx,dot.cy,dot.cradius,dot.paint)
}
}
}

《实例 -自定义绘制滑动解锁.doc》

下载本文的Word格式文档,以方便收藏与打印。