android开发之Android 自定义滑动解锁View

自定义滑动解锁View

  1. 需求如下:

近期需要做一个类似屏幕滑动解锁的功能,右划开始,左划暂停。

  1. 需求效果图如下
    IMG_256
  2. 实现效果展示
    IMG_257
  3. 自定义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传进来

  1. 调用方式如下

/**

  • 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专做工具类,大概就这样。

文章来源:网络 版权归原作者所有

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/35342.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构——线性表

文章目录 线性表的定义和基本操作顺序表线性表的链式表示 线性表的定义和基本操作 线性表是具有相同数据类型的(n≥0)个数据元素的有限序列&#xff0c;其中n为表长&#xff0c;当n0时线性表是一个空表。若用L命名线性表&#xff0c;则其中一般表示为&#xff1a;L(a1,a2,a3, …

.NET实现解析字符串表达式

一、引子功能需求 我们创建了一个 School 对象&#xff0c;其中包含了教师列表和学生列表。现在&#xff0c;我们需要计算教师平均年龄和学生平均年龄。 //创建对象 School school new School() {Name "小菜学园",Teachers new List<Teacher>(){new Teach…

CCLINK转MODBUS-TCP网关cclink通讯接线图 终端电阻

大家好&#xff0c;今天我们要聊的是生产管理系统中的CCLINK和MODBUS-TCP协议&#xff0c;它们的不同使得数据互通比较困难&#xff0c;但捷米JM-CCLK-TCP网关的出现改变了这一切。 1捷米JM-CCLK-TCP是一款自主研发的CCLINK从站功能的通讯网关&#xff0c;它的主要功能是将各种…

后端开发5.Redis的搭建

使用docker安装 Redis【redis】(6379) 拉取Redis镜像 docker pull redis:6.2.6 启动Redis容器 docker run -di --name=redis -p 6379:6379 redis:6.2.6 启动Redis容器并设置密码 docker run -di --name=redis -p 6379:6379 redis:6.2.6 --requirepass "密码" 测…

D455+VINS-Fusion+surfelmapping 稠密建图(三)

继续&#xff0c;由surfelmapping建立的点云生成octomap八叉树栅格地图 一、安装OctomapServer 建图包 安装插件 sudo apt-get install ros-melodic-octomap-ros sudo apt-get install ros-melodic-octomap-msgs sudo apt-get install ros-melodic-octomap-server sudo apt-…

cubemx hal stm32 舵机 可减速 任意位置停止 驱动代码

CubeMX配置 对于 STM32 F407VE 这里的84是来自APB1那路2倍频得到&#xff1a; 代码部分 两个舵机都是180度的 servo.c #include "servo.h" #include "tim.h" #include "stdio.h"__IO uint32_t g_SteerUWT[2] {0}; uint16_t g_SteerDeg[…

React Native Maps的使用

介绍 React Native Maps是一个用于在React Native应用中显示地图的库。它提供了许多功能&#xff0c;如显示地图、标记位置、绘制多边形等。以下是React Native Maps的使用步骤&#xff1a; 使用 首先&#xff0c;你需要在你的React Native项目中安装React Native Maps库。可…

青大数据结构【2014】

一、单选 二、简答 为了解决顺序队列的假溢出问题&#xff0c;提出了循环队列&#xff0c;即把存储队列的表从逻辑上看成一个环 判别队列空和满有三种方法&#xff1a; 1&#xff09;采用计数器判别&#xff0c;空时&#xff0c;计数器为0&#xff1b;满时&#xff0c;计数器…

【设计模式——学习笔记】23种设计模式——中介者模式Mediator(原理讲解+应用场景介绍+案例介绍+Java代码实现)

文章目录 案例引入案例一普通实现中介者模式 案例二 介绍基础介绍登场角色尚硅谷 《图解设计模式》 案例实现案例一&#xff1a;智能家庭类图实现 案例二&#xff1a;登录页面逻辑实现说明类图实现 总结文章说明 案例引入 案例一 普通实现 在租房过程中&#xff0c;客户可能…

css 实现 html 元素内文字水平垂直居中的N种方法

上一篇博文写了div 中元素居中的N种常用方法&#xff0c;那么单个html元素&#xff1a;div&#xff08;块级元素代表&#xff09;&#xff0c;span&#xff08;行内元素代表&#xff09;中的文字如何水平垂直都居中呢&#xff1f;实现方法如下&#xff1a; 本文例子使用的 html…

WebAPIs 第二天

DOM事件基础 事件监听事件类型事件对象 一.事件监听 ① 概念&#xff1a;就是让程序检测是否有事件发生&#xff0c;一旦有事件触发&#xff0c;就立即调用一个函数做出响应&#xff0c;也成为绑定事件或者注册事件 ② 语法&#xff1a;元素对象.addEventListener(事件类型&…

机器学习---对数几率回归

1. 逻辑回归 逻辑回归&#xff08;Logistic Regression&#xff09;的模型是一个非线性模型&#xff0c; sigmoid函数&#xff0c;又称逻辑回归函数。但是它本质上又是一个线性回归模型&#xff0c;因为除去sigmoid映射函 数关系&#xff0c;其他的步骤&#xff0c;算法都是…

从零开始,贪吃蛇小游戏系列专栏完美收官!

&#x1f3ae; 从零开始&#xff0c;贪吃蛇小游戏系列专栏完美收官&#xff01; &#x1f40d; 各位游戏开发探索者们&#xff0c;大家好&#xff01;我是[亿元程序员]&#xff0c;一位拥有8年游戏开发经验的主程。经过一段时间的努力&#xff0c;我很高兴地宣布&#xff0c;我…

阿里云预装LAMP应用导致MySQL不显示访问密码如何解决

&#x1f600;前言 本篇博文是关于阿里云云服务器ECS部署MySQL过程中出现的一下坑&#xff0c;希望能够帮助到您&#x1f60a; &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家…

SUB-1G SOC芯片DP4306F 32 位 ARM Cortex-M0+内核替代CMT2380F32

DP4306F是一款高性能低功耗的单片集成收发机&#xff0c;集成MO核MCU&#xff0c;工作频率可覆盖200MHiz^ 1000MHz。 支持230/408/433/470/868/915频段。该芯片集成了射频接收器、射频发射器、频率综合器、GFSK调制器、GFSK解调器等功能模块。通过SPI接口可以对输出功率、频道选…

gitlab-Runner搭建

root wget https://packages.gitlab.com/runner/gitlab-runner/packages/fedora/29/gitlab-runner-12.6.0-1.x86_64.rpm/download.rpm rpm -ivh download.rpm ---- 安装 rpm -Uvh download.rpm -----更新升级 然后运行&#xff1a; gitlab-runner register --url https://git…

RabbitMQ相关面试题

用到了哪些MQ?什么使用场景?MQ的组成部分?MQ宕机了怎么办?如何进行持久化的? MQ的选型? Kafka:高吞吐量、低延迟的分布式消息队列,主要用于大规模数据处理和流式处理 RocketMQ:RocketMQ是阿里巴巴开源的分布式消息队列,具有高吞吐量、低延迟、高可靠性等特点 RabbitM…

【Go 基础篇】Go语言浮点类型:探索浮点数的特点与应用

介绍 浮点数是计算机编程中用于表示实数的一种数据类型&#xff0c;用于处理具有小数部分的数值。Go语言&#xff08;Golang&#xff09;提供了两种主要的浮点数类型&#xff1a;float32和float64&#xff0c;分别用于单精度和双精度浮点数的表示。本篇博客将深入探讨Go语言中…

38 | 浦发银行股票分析案例

本文将通过一个浦发银行股票分析案例,探讨如何从多个维度对股票进行分析,包括基本面、技术面和市场环境等因素。我们将深入挖掘浦发银行的财务数据、业务模式以及市场定位,以了解其内在价值和潜在风险。同时,我们还将考察技术面的指标,如价格走势、均线形态等,以揭示市场…

linux 命令--常用关机命令

1.使用shutdown命令 shutdown命令是Linux系统下最常用的关机命令之一。它可以让系统在指定时间内进行关机或者重启操作。例如&#xff0c;下面的命令可以让系统在5分钟后进行关机操作&#xff1a; sudo shutdown -h5其中&#xff0c;“-h”表示关机&#xff0c;“5”表示5分钟…