评论

收藏

[Android] 实例

移动开发 移动开发 发布于:2021-06-25 10:03 | 阅读数:366 | 评论:0

  效果图:
DSC0000.png     DSC0001.png     DSC0002.png

  GitHub地址:https://github.com/luofangli/Draw_SlideUnclock
  全部代码:
  1:
DSC0003.png
<?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:
DSC0004.png
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:
DSC0005.png
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)
    }
  }
}
关注下面的标签,发现更多相似文章