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进行实战操…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
解锁数据库简洁之道:FastAPI与SQLModel实战指南
在构建现代Web应用程序时,与数据库的交互无疑是核心环节。虽然传统的数据库操作方式(如直接编写SQL语句与psycopg2交互)赋予了我们精细的控制权,但在面对日益复杂的业务逻辑和快速迭代的需求时,这种方式的开发效率和可…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...
第7篇:中间件全链路监控与 SQL 性能分析实践
7.1 章节导读 在构建数据库中间件的过程中,可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中,必须做到: 🔍 追踪每一条 SQL 的生命周期(从入口到数据库执行)&#…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
windows系统MySQL安装文档
概览:本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容,为学习者提供全面的操作指导。关键要点包括: 解压 :下载完成后解压压缩包,得到MySQL 8.…...
