直接上代码了:

/****@ClassName:GraphicsView*@author:WYL*@Date:2022/9/29*/
class GraphicsView : View {private var mWidth = 0private 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 = truestyle = Paint.Style.FILLisDither = true}}private val linePaint: Paint by lazy {Paint(Paint.ANTI_ALIAS_FLAG).apply {isAntiAlias = truestyle = Paint.Style.FILLisDither = truestrokeWidth = 10fmPaint.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 = mWidthsetMeasuredDimension(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 / 3fval averageHeight = mHeight / 3ffor (i in 0 until 3) {for (j in 0 until 3) {graphicsPoints[i * 3 + j].apply {x = (averageWidth * (j + 1)) - averageWidth / 2fy = (averageHeight * (i + 1)) - averageHeight / 2f}}}var startX = 0fvar startY = 0fvar stopX = 0fvar stopY = 0fcheckGraphicsPoints.forEachIndexed { index, it ->if (index > 0) {stopX = it.xstopY = it.ycanvas?.drawLine(startX, startY, stopX, stopY, linePaint)startX = stopXstartY = stopY} else {startX = it.xstartY = it.y}}if (continueJudge) {canvas?.drawLine(startX, startY, currentX, currentY, linePaint)}graphicsPoints.forEach {if (it.isSelect) {mPaint.color = selectColorTransparentcanvas?.drawCircle(it.x, it.y, radius, mPaint)mPaint.color = selectColorcanvas?.drawCircle(it.x, it.y, radius/3, mPaint)} else {mPaint.color = unselectColorcanvas?.drawCircle(it.x, it.y, radius/3, mPaint)}}}/*** 判断滑动时是否去判断*/private var continueJudge = falseprivate var currentX = 0fprivate var currentY = 0foverride 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 = trueit.isSelect = truecheckGraphicsPoints.add(it)currentX = event.xcurrentY = event.yinvalidate()return@forEach}}}MotionEvent.ACTION_MOVE -> {if (continueJudge) {currentX = event.xcurrentY = event.yinvalidate()}graphicsPoints.forEach {if (judgeCircle(it, event.x, event.y) && !it.isSelect) {//Log.e(GraphicsView::class.java.canonicalName, "在圆点里面!!!!!!!!!!!!!")it.isSelect = truecheckGraphicsPoints.add(it)if (!continueJudge) {currentX = event.xcurrentY = event.ycontinueJudge = 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 = falsecheckGraphicsPoints.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 = 0fvar y = 0fvar type: Int = -1var isSelect = falseconstructor(x: Float, y: Float, type: Int) {this.x = xthis.y = ythis.type = type}constructor(type: Int) {this.type = type}}var onResultListener:OnResultListener? = nullinterface OnResultListener{fun onResult(password:String)}}

效果图:

Android 自定义手势解锁View相关推荐

  1. android view显示隐藏动画效果,Android 根据手势顶部View自动展示与隐藏效果

    首先来看一下效果: 大体思路如下: 总体布局用了一个自定义的ViewGroup,里面包了两个View(top View,bottomView) 我在bottomView里放了ViewPager,里面又 ...

  2. android自定义滑块解锁,android 滑动解锁

    通过android自定义View实现横向的滑动解锁,1.滑动到中间会自动返回到原始的位置,2.滑动到底部会自动解锁,会触发解锁的回调:首先看效果图如下: 实现以上部分一共分为三部分: 其中背景通过sh ...

  3. android自定义手势,Android编程实现自定义手势的方法详解

    本文实例讲述了Android编程实现自定义手势的方法.分享给大家供大家参考,具体如下: 之前介绍过如何在Android程序中使用手势,主要是系统默认提供的几个手势,这次介绍一下如何自定义手势,以及如何 ...

  4. android自定义手势,Android实现自定义手势和识别手势的功能

    这篇文章主要介绍了Android实现自定义手势和识别手势的功能,本文通过实例代码给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下 1. 先完成自定义手势的Activity 1.1 因 ...

  5. 自定义手势解锁锁控件

    一.控件的使用 模仿市面上app的手势解锁功能,实现的小控件,将控件封装到了一个UIView上 二.核心原理技术 1.触摸事件 (1)UIView的触摸三个触摸响应事件:开始.移动.结束 (2)CGR ...

  6. Android实现手势解锁

    自己实现过一个手势解锁, 觉得有一点用, 所以贴出来便于以后使用. 需求 9宫格解锁, 连接节点后, 节点之间会绘制连线. 节点被连接后会变色. 当手指继续绘制手势时, 最后一个节点会延伸出一条连线跟 ...

  7. android的手势解锁功能,Android应用开发之Android 5秒学会使用手势解锁功能

    本文将带你了解Android应用开发Android 5秒学会使用手势解锁功能,希望本文对大家学Android有所帮助. Android手势解锁 本文讲述的是一个手势解锁的库,可以定制显示隐藏宫格点.路 ...

  8. Android 自定义手势键盘

    自定义手势键盘 手势键盘有三种状态,初始状态.点击状态和错误状态,分别以下列三个图片显示. 2. 数据类CircleArea CircleArea类用来记录手势键盘的信息. static class ...

  9. android自定义滑块解锁,使用Android自定义控件实现滑动解锁九宫格

    本文概述: 滑动解锁九宫格的分析: 1.需要自定义控件: 2.需要重写事件onTouchEvent(); 3.需要给九个点设置序号和坐标,这里用Map类就行: 4.需要判断是否到滑到过九点之一,并存储 ...

最新文章

  1. 全面升级!星环科技基础软件再升级,赋能数字中国建设
  2. 业余草 SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本)
  3. 仅用六个字符来完成Hello World,你能做到吗?
  4. 制作基于http的yum源2
  5. 一个PHP程序的“怪问题”
  6. 【异步编程学习笔记】JDK中的FutureTask和CompletableFuture详解(使用示例、源码)
  7. 有关linux下redis overcommit_memory的问题,以及导致的:Cannot allocate memory问题
  8. 关于Android工程师转vue的三两事儿(10)--原型与原型链
  9. 〖Linux〗VirtualBox修改虚拟电脑硬盘(vdi)空间大小
  10. iOS 9 Safari广告拦截插件
  11. python大漠插件官网视频教程_python使用大漠插件进行脚本开发的尝试(一)
  12. QQ电脑管家 vs 360 安全助手 (客观+主观)
  13. 【58同城和赶集网简历下载获取】
  14. LA4487 加权并查集
  15. Chrome保存整个网页为图片、PDF
  16. python数据录入和分析_基于 Python 和 Pandas 的数据分析(3) --- 输入/输出 基础
  17. openstack虚拟机无法获取IP地址
  18. 华为云麒麟arm架构docker启动redis报错:<jemalloc>: Unsupported system page size
  19. cad怎么倒圆角_15个超实用CAD技巧,效率递增10倍,设计院师傅都在用
  20. Joomla version 1.5.12 suffers from path disclosure and local file inclusion vulnerabilities.

热门文章

  1. 使用fla格式作为美术资源管理的利弊
  2. RT-Thread GD32F4xx 看门狗驱动
  3. 三本院校本科毕业,华科博士入选华为“天才少年”,年薪200万,网友:最酷逆袭
  4. 儿童上网时间管控软件_GreenSurfOnline V0.1 使用说明 (以Windows后台服务形式存在,安装需要有一定电脑操作基础)...
  5. 计算机信息世界PPT,奇妙的信息世界课件.ppt
  6. KFS同步过程中遇到的问题
  7. 在控制台输入举行场合宽并求出其周长和面积
  8. kindeditor去掉图片空间
  9. 硅谷首富:拉里 埃里森 1
  10. 神舟战神win10改linux,神州战神G40把win10改成win7的详细教程(包括BIOS设置图)