android开发之Android 自定义滑动解锁View
自定义滑动解锁View
- 需求如下:
近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。
- 需求效果图如下
- 实现效果展示
- 自定义view如下
/**
-
Desc 自定义滑动解锁View
-
Author ZY
-
Mail sunnyfor98@gmail.com
-
Date 2021/5/17 11:52
*/
@SuppressLint(“ClickableViewAccessibility”)
class SlideSwitchButton : ViewGroup {
constructor(context: Context?) : this(context, null)constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0)constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : this(context,attrs,defStyleAttr, 0)constructor(context: Context?,attrs: AttributeSet?,defStyleAttr: Int,defStyleRes: Int) : super(context, attrs, defStyleAttr, defStyleRes)var duration = 300var isOpen = falsevar scrollView: ScrollView? = nullvar onSwitchListener: ((isOpen: Boolean) -> Unit)? = nullprivate var itemHeight = 0private var itemPadding = 0private var parentWidth = 0private val stopImgView: ImageView by lazy {ImageView(context).apply {setImageResource(R.drawable.f1_svg_btn_stop)}}private val startImgView: ImageView by lazy {ImageView(context).apply {setImageResource(R.drawable.f1_svg_btn_start)}}private val hintView: TextView by lazy {TextView(context).apply {setTextSize(TypedValue.COMPLEX_UNIT_PX, resources.getDimension(R.dimen.dp_14))compoundDrawablePadding = resources.getDimension(R.dimen.dp_5).toInt()setTextColor(Color.parseColor("#727b9f"))}}init {setBackgroundResource(R.drawable.f1_sel_bg_slide_btn)addView(hintView)updateHint()addView(stopImgView)addView(startImgView)var x = 0startImgView.setOnTouchListener { v, event ->when (event.action) {MotionEvent.ACTION_DOWN -> {scrollView?.requestDisallowInterceptTouchEvent(true)x = event.x.toInt()}MotionEvent.ACTION_UP -> {if (startImgView.x < (parentWidth - startImgView.width) / 2) {play(false)} else {play(true)}scrollView?.requestDisallowInterceptTouchEvent(false)}MotionEvent.ACTION_MOVE -> {val lastX = event.x - xif (startImgView.x + lastX > parentWidth - itemPadding - startImgView.width) {return@setOnTouchListener true}if (startImgView.x + lastX < itemPadding) {return@setOnTouchListener true}startImgView.x += lastX}}return@setOnTouchListener true}}override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {super.onMeasure(widthMeasureSpec, heightMeasureSpec)setMeasuredDimension(widthMeasureSpec, resources.getDimension(R.dimen.dp_90).toInt())itemPadding = resources.getDimension(R.dimen.dp_5).toInt()itemHeight = resources.getDimension(R.dimen.dp_80).toInt()parentWidth = MeasureSpec.getSize(widthMeasureSpec)}override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {stopImgView.layout(itemPadding,itemPadding,itemPadding + itemHeight,itemPadding + itemHeight)startImgView.layout(itemPadding,itemPadding,itemPadding + itemHeight,itemPadding + itemHeight)val len =hintView.paint.measureText(hintView.text.toString()) + resources.getDimension(R.dimen.dp_24)val let = (r - len) / 2hintView.layout(let.toInt(),resources.getDimension(R.dimen.dp_35).toInt(),(let + len).toInt(),resources.getDimension(R.dimen.dp_55).toInt())}/*** flag tue为开始 false为停止*/private fun play(flag: Boolean) {val mStart = startImgView.xval mEnd = if (flag) {parentWidth - itemPadding * 2 - startImgView.width.toFloat()} else {stopImgView.x - itemPadding}val animatorOBJ =ObjectAnimator.ofFloat(startImgView, "translationX", mStart, mEnd)animatorOBJ.duration = duration.toLong()animatorOBJ.addListener(object : Animator.AnimatorListener {override fun onAnimationRepeat(animation: Animator?) {}override fun onAnimationEnd(animation: Animator?) {updateHint(flag)if (flag != isOpen) {isOpen = flagonSwitchListener?.invoke(flag)}}override fun onAnimationCancel(animation: Animator?) {}override fun onAnimationStart(animation: Animator?) {}})animatorOBJ.start()}private fun updateHint(lock: Boolean = false) {val icon = if (lock) {hintView.text = "滑动停止"ResourcesCompat.getDrawable(resources, R.drawable.f1_svg_left_arrow, null)} else {hintView.text = "滑动开始"ResourcesCompat.getDrawable(resources, R.drawable.f1_svg_right_arrow, null)}icon?.setBounds(0,0,resources.getDimension(R.dimen.dp_14).toInt(),resources.getDimension(R.dimen.dp_12).toInt())if (lock) {hintView.setCompoundDrawables(icon, null, null, null)} else {hintView.setCompoundDrawables(null, null, icon, null)}}fun stop() {play(false)}fun start() {play(true)}
}
这里需要注意一点:页面过长时,ScrollView和SlideSwitchButton滑动事件会冲突,所以需要吧scrollView传进来
- 调用方式如下
/**
-
Desc 自定义滑动解锁View
-
Author ZY
-
Mail sunnyfor98@gmail.com
-
Date 2021/5/28 17:48
*/
class SlideSwitchButtonActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.f1_act_main)btn_start.scrollView = scrollViewbtn_start.onSwitchListener = {if (it) {Toast.makeText(this,"开始操作",Toast.LENGTH_LONG).show()btn_start.start()} else {Toast.makeText(this,"停止操作",Toast.LENGTH_LONG).show()btn_start.stop()}}}
}
之前封装了一版ZyFrame框架,集工具类、自定义组件、网络请求框架一体,感觉用起来有些厚重,接下来会抽时间做拆分,ZyFrame保留网络请求功能,ZyUI专做自定义组件,ZyTool专做工具类,大概就这样。
文章来源:网络 版权归原作者所有
上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理
相关文章:

android开发之Android 自定义滑动解锁View
自定义滑动解锁View 需求如下: 近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。 需求效果图如下 实现效果展示 自定义view如下 /** Desc 自定义滑动解锁View Author ZY Mail sunnyfor98gmail.com Date 2021/5/17 11:52 *…...

CAD绘制法兰、添加光源、材质并渲染
首先绘制两个圆柱体,相互嵌套 在顶部继续绘制圆柱体,这是之后要挖掉的部分 在中央位置绘制正方形 用圆角工具: 将矩形的四个角分别处理,效果: 用拉伸工具 向上拉伸到和之前绘制的圆柱体高度齐平 绘制一个圆柱体&#…...

ChatGPT访问流量下降的原因分析
自从OpenAI的ChatGPT于11月问世以来,这款聪明的人工智能聊天机器人就席卷了全世界,人们在试用该工具的同时也好奇该技术到底将如何改变我们的工作和生活。 但近期Similarweb表示,自去ChatGPT上线以来,该网站的访问量首次出现下…...

干货 | 详述 Elasticsearch 向量检索发展史
1. 引言 向量检索已经成为现代搜索和推荐系统的核心组件。 通过将复杂的对象(例如文本、图像或声音)转换为数值向量,并在多维空间中进行相似性搜索,它能够实现高效的查询匹配和推荐。 图片来自:向量数据库技术鉴赏【上…...
mysql常见面试题,高频题目放送
互联网的产品架构是包含这接入层,逻辑处理以及储存层的,其中储存层承载着较多的数据以及持久化的任务,而说到储存层,避免不了说到数据库,在我们面试的时候,数据库的知识题目占比是非常多的: 1.…...

使用 PowerShell 将 Excel 中的每个工作表单独另存为独立的文件
导语:在日常工作中,我们经常需要处理 Excel 文件。本文介绍了如何使用 PowerShell 脚本将一个 Excel 文件中的每个工作表单独另存为独立的 Excel 文件,以提高工作效率。 1. 准备工作 在开始之前,请确保已经安装了 Microsoft Exc…...
python提取pdf图片
import fitz import re import osdef save_pdf_img(path, save_path):path: pdf的路径save_path : 图片存储的路径# 使用正则表达式来查找图片checkXO r"/Type(? */XObject)"checkIM r"/Subtype(? */Image)"# 打开pdfdoc fitz.open(path)# 图片计数im…...

Vue3 表单输入绑定简单应用
去官网学习→表单输入绑定 | Vue.js 运行示例: 代码:HelloWorld.vue <template><div class"hello"><h1>Vue 表单输入绑定</h1><input type"text" placeholder"输入框" v-model"msg"…...

如何解决 Elasticsearch 查询缓慢的问题以获得更好的用户体验
作者:Philipp Kahr Elasticsearch Service 用户的重要注意事项:目前,本文中描述的 Kibana 设置更改仅限于 Cloud 控制台,如果没有我们支持团队的手动干预,则无法进行配置。 我们的工程团队正在努力消除对这些设置的限制…...

近期学习练习
练习: 或: //sqrt是数学库函数,开平方 //头文件为math.h 或...
平台安全之中间件安全
理解中间件 一次web访问的顺序,web浏览器->web服务器(狭义)->web容器->应用服务器->数据库服务器 web服务器 广义:提供广义web服务的软件或主机 狭义:提供w3服务的软件或主机,即Web服务器软件…...

芒果 TV 基于 Flink 的实时数仓建设实践
公司简介:芒果 TV 作为湖南广电旗下互联网视频平台,在“一云多屏,多元一体”的战略指导下,通过内容自制,培植核心竞争力,从独播、独特走向独创,并通过市场化运作完成 A 轮、B 轮融资,…...

尚硅谷大数据项目《在线教育之采集系统》笔记004
视频地址:尚硅谷大数据项目《在线教育之采集系统》_哔哩哔哩_bilibili 目录 P047 P048 P049 P050 P051 P052 P053 P054 P055 P056 P047 /opt/module/datax/job/base_province.json [atguigunode001 ~]$ hadoop fs -mkdir /base_province/2022-02-22 [atgu…...

R语言4_安装BayesSpace
环境Ubuntu22/20, R4.1 你可能会报错说你的R语言版本没有这个库,但其实不然。这是一个在Bioconductor上的库。 同时我也碰到了这个问题,ERROR: configuration failed for package systemfonts’等诸多类似问题,下面的方法可以一并解决。 第…...

TSINGSEE青犀视频安防监控视频平台EasyCVR设备在线,视频无法播放的原因排查
可支持国标GB28181、RTMP、RTSP/Onvif、海康Ehome、海康SDK、大华SDK、宇视SDK等多种协议接入的安防监控视频平台EasyCVR基于云边端一体化架构,具有强大的数据接入、处理及分发能力,可在复杂的网络环境中,将分散的各类视频资源进行统一汇聚、…...

【算法篇C++实现】算法的时间、空间复杂度
文章目录 🚀一、算法的概念🚀二、算法的特征1.可行性2.确定性3.有穷性4.输入5.输出 🚀三、算法的评价1.正确性2.可读性3.健壮性 🚀四、算法的复杂度⛳(一)时间复杂度1、时间复杂度的概念2、大O的渐进表示法…...

On Evaluation of Embodied Navigation Agents 论文阅读
论文信息 题目:On Evaluation of Embodied Navigation Agents 作者:Peter Anderson,Angel Chang 来源:arXiv 时间:2018 Abstract 过去两年,导航方面的创造性工作激增。这种创造性的输出产生了大量有时不…...
【CSS 布局】水平垂直方向居中
【CSS 布局】水平垂直方向居中 单行元素 <div class"container"><div class"item"></div> </div>方式一:relative 和 absolute .container {position: relative;height: 400px;border: 1px solid #ccc;.item {posit…...

Java实现轻量型Web服务器接收http协议提交的RFID读卡信息
示例使用的读卡器:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.ServerSock…...

模拟实现消息队列项目(完结) -- 基于MQ的生产者消费者模型
目录 前言 1. 生产者 2. 消费者 3. 启动消息队列服务器 4. 运行效果 结语 前言 在上一章节,我们完成了消息队列的客户端部分,至此我们整个消息队列项目就构建完成了,那我们做的这个消息队列到底有什么效果,以及如何去使用我们自己的消息队列呢?那么本文,就将我们的MQ进行实战操…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...

1.3 VSCode安装与环境配置
进入网址Visual Studio Code - Code Editing. Redefined下载.deb文件,然后打开终端,进入下载文件夹,键入命令 sudo dpkg -i code_1.100.3-1748872405_amd64.deb 在终端键入命令code即启动vscode 需要安装插件列表 1.Chinese简化 2.ros …...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...

2025 后端自学UNIAPP【项目实战:旅游项目】6、我的收藏页面
代码框架视图 1、先添加一个获取收藏景点的列表请求 【在文件my_api.js文件中添加】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http…...

PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...

华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...