Android:将自定义视图设为互动式

一、简介

点击查看将自定义视图设为互动式官网文档

绘制界面只是创建自定义视图的一个部分。您还需要让视图以非常类似于您模仿的真实操作的方式响应用户输入。

让应用中的对象的行为方式与真实对象相似。例如,不要让应用中的图片消失后重新出现在其他位置,因为现实世界中的对象不会这样做。而是应该将图片从一个位置移动到另一个位置。

用户可以感受到界面中的细微行为或感觉,并对模仿现实世界的细微差别做出最佳反应。例如,当用户快滑界面对象时,在开始时为用户提供一种惯性感,以延迟移动。在动作结束时,让他们感受到使物体超出快滑范围的动量。

本页演示了如何使用 Android 框架的功能将这些真实行为添加到您的自定义视图中。

如需了解其他相关信息,请参阅输入事件概览和属性动画概览。

二、处理输入手势

像许多其他界面框架一样,Android 支持输入事件模型。用户操作会转换为触发回调的事件,您可以替换回调以自定义应用对用户的响应方式。Android 系统中最常见的输入事件是“轻触”,会触发 onTouchEvent(android.view.MotionEvent)。您可以重写此方法来处理事件,如下所示:

override fun onTouchEvent(event: MotionEvent): Boolean {return super.onTouchEvent(event)
}

触摸事件本身并不是特别有用。现代触控界面根据手势定义互动,例如点按、拉、推、快滑和缩放。为了将原始轻触事件转换为手势,Android 提供了 GestureDetector。

通过传入实现 GestureDetector.OnGestureListener 的类的实例来构建 GestureDetector。如果您只想处理几个手势,可以扩展 GestureDetector.SimpleOnGestureListener,而不是实现 GestureDetector.OnGestureListener 接口。例如,以下代码会创建一个扩展 GestureDetector.SimpleOnGestureListener 并替换 onDown(MotionEvent) 的类。

private val myListener =  object : GestureDetector.SimpleOnGestureListener() {override fun onDown(e: MotionEvent): Boolean {return true}
}private val detector: GestureDetector = GestureDetector(context, myListener)

无论您是否使用 GestureDetector.SimpleOnGestureListener,请始终实现返回 true 的 onDown() 方法。这是必要的,因为所有手势都以 onDown() 消息开头。如果您从 onDown() 返回 false(就像 GestureDetector.SimpleOnGestureListener 一样),系统会假设您想要忽略其余手势,并且不会调用 GestureDetector.OnGestureListener 的其他方法。仅当您想要忽略整个手势时,才从 onDown() 返回 false。

实现 GestureDetector.OnGestureListener 并创建 GestureDetector 的实例后,您可以使用 GestureDetector 解读在 onTouchEvent() 中收到的触摸事件。

override fun onTouchEvent(event: MotionEvent): Boolean {return detector.onTouchEvent(event).let { result ->if (!result) {if (event.action == MotionEvent.ACTION_UP) {stopScrolling()true} else false} else true}
}

当您向 onTouchEvent() 传递无法被识别为手势一部分的触摸事件时,它会返回 false。然后,您可以运行自己的自定义手势检测代码。

三、创建物理上合理的动作

手势是控制触摸屏设备的一种强大方式,但它们可能违背常理且难以记住,除非它们产生物理上合理的结果。

例如,假设您想要实现一个水平快速滑动手势,用于设置在视图中绘制的项目围绕其垂直轴旋转。如果界面的响应方式是沿快滑方向快速移动,然后放慢速度,就好像用户推动飞轮并使其旋转一样,这种手势很合理。

有关如何为滚动手势添加动画效果的文档详细介绍了如何实现您自己的滚动行为。但模拟飞轮的感觉并非易事。要使飞轮模型正常工作,需要运用大量的物理知识和数学运算。幸运的是,Android 提供了辅助类来模拟此行为和其他行为。Scroller 类是处理飞轮式快速滑动手势的基础。

如需开始快滑,请调用 fling() 并传入初始速度以及快滑的最小和最大 x 值和最大 y 值。对于速度值,您可以使用由 GestureDetector 计算的值。

在这里插入图片描述

fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean {scroller.fling(currentX,currentY,(velocityX / SCALE).toInt(),(velocityY / SCALE).toInt(),minX,minY,maxX,maxY)postInvalidate()return true
}

注意: 虽然由 GestureDetector 计算的速度在物理上是准确的,但许多开发者认为使用此值会导致快滑动画速度过快。常见的做法是将 x 速度和 y 速度除以四到八的倍数。

调用 fling() 将设置快滑手势的物理模型。之后,通过定期调用 Scroller.computeScrollOffset() 来更新 Scroller。computeScrollOffset() 通过读取当前时间并使用物理模型计算当时的 x 和 y 位置,从而更新 Scroller 对象的内部状态。调用 getCurrX() 和 getCurrY() 可检索这些值。

大多数视图会将 Scroller 对象的 x 和 y 位置直接传递给 scrollTo()。此示例略有不同:它使用当前的滚动 x 位置来设置视图的旋转角度。

scroller.apply {if (!isFinished) {computeScrollOffset()setItemRotation(currX)}
}

Scroller 类会为您计算滚动位置,但不会自动将这些位置应用到视图。应经常应用新坐标,以保证滚动动画的流畅性。您可以采用下列两种方法:

  • 调用 fling() 后调用 postInvalidate(),以强制重新绘制。此方法要求您在 onDraw() 中计算滚动偏移,并在每次滚动偏移发生变化时调用 postInvalidate()。
  • 设置 ValueAnimator 以在快滑期间添加动画效果,并通过调用 addUpdateListener() 添加监听器以处理动画更新。 通过此方法,您可以为 View 的属性添加动画效果。

四、让转场更顺畅

用户希望现代界面能够在状态之间流畅过渡:界面元素应淡入和淡出,而不是出现和消失;动作开始和结束平稳,而不是突然开始和停止。Android 属性动画框架可以更轻松地实现平滑过渡。

如需使用动画系统,每当属性更改会影响视图外观时,请勿直接更改该属性,请改用 ValueAnimator 进行更改。在以下示例中,修改视图中的选定子组件会使整个渲染视图旋转,使选择指针居中。ValueAnimator 会用几百毫秒的时间更改旋转,而不是立即设置新的旋转值。

autoCenterAnimator = ObjectAnimator.ofInt(this, "Rotation", 0).apply {setIntValues(targetAngle)duration = AUTOCENTER_ANIM_DURATIONstart()
}

如果您要更改的值是基本 View 属性之一,则可以更轻松地执行动画,因为视图具有针对多个属性同时播放动画进行了优化的内置 ViewPropertyAnimator,如以下示例所示:

animate().rotation(targetAngle).duration = ANIM_DURATION.start()

五、优化自定义视图

如果您有一个精心设计的视图可以响应手势和状态之间的转换,请确保该视图快速运行。为避免播放过程中界面响应缓慢或卡顿,请确保动画始终以每秒 60 帧的速度运行。

5.1 加快观看速度

为了提高视图的运行速度,可从频繁调用的例程中剔除不必要的代码。从 onDraw() 开始,这将为您带来最大的回报。特别是应消除 onDraw() 中的分配,因为分配可能会导致垃圾回收,从而造成卡顿。请在初始化期间或动画之间分配对象。切勿在动画运行期间进行分配。

除了精简 onDraw() 之外,还应确保尽可能降低调用它的频率。对 onDraw() 的大多数调用都是调用 invalidate() 的结果,因此可以避免不必要的 invalidate() 调用。

另一种成本非常高昂的操作是遍历布局。当视图调用 requestLayout() 时,Android 界面系统会遍历整个视图层次结构,以确定每个视图所需的大小。如果发现冲突的测量值,可能会多次遍历层次结构。界面设计人员有时会创建由嵌套的 ViewGroup 对象组成的深层次结构。这些深层视图层次结构会导致性能问题,因此应尽可能浅层视图。

如果您的界面比较复杂,不妨考虑编写自定义 ViewGroup 来执行其布局。与内置视图不同,自定义视图可以对其子项的尺寸和形状做出特定于应用的假设,从而避免遍历其子项以计算测量值。

例如,如果您有一个自定义 ViwGroup,它不通过调整自身大小来适应其所有子视图,就可以避免测量所有子视图所产生的开销。如果您使用适合各种用例的内置布局,则无法进行此优化。

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

防洪墙的安全内容检测+http请求头

1、华为的IAE引擎:内部工作过程 IAE引擎主要是针对2-7层进行一个数据内容的检测 --1、深度检测技术 (DPI和DPF是所有内容检测都必须要用到的技术) ---1、DPI--深度包检测,针对完整的数据包,进行内容的识别和检测 1、基于特征子的检…

使用Django框架实现音频上传功能

数据库设计(models.py) class Music(models.Model):""" 音乐 """name models.CharField(verbose_name"音乐名字", max_length32)singer models.CharField(verbose_name"歌手", max_length32)# 本质…

「51媒体」广东展览展会媒体宣传,媒体邀约名单

传媒如春雨,润物细无声,大家好,我是51媒体网胡老师。 广州作为最具经济活力的省份之一,每年大大小小的展会吸引着全球的客商,在展览展会期间能邀请哪些媒体来报道宣传呢? 广东展览展会媒体宣传的媒体邀约名…

sourcrinlight 4.0 的使用技巧:如何在文件名后省略路径名

如图: 如果路径名很长,将显示不了几个文件名的,会造成一些不便。如何隐藏文件的路径名呢? 选中或取消这个按钮: 就可以了。要想再查看文件路径,鼠标放上去,就会显示了: 谢谢

2024最新Cloudways主机使用教程(含最新Cloudways折扣码)

Cloudways是一家提供云托管服务的公司,可以帮助你轻松管理和运行你的网站。本教程是Cloudways主机注册和使用教程。Cloudways界面简洁,使用方便,不需要复杂的设置,就能快速搭建一个WordPress网站。它的主机功能包括高级缓存和Bree…

Electron案例解析-获取 Chrome、Node.js和Electron版本号的应用案例

实现效果 目录结构 index.html <!DOCTYPE html> <html> <head><meta charset"UTF-8" /><!-- 内容安全策略--><metahttp-equiv"Content-Security-Policy"content"default-src self; script-src self"/><…

微信公众平台无限回调系统 /user/ajax.php SQL注入漏洞复现

0x01 产品简介 微信公众平台无限回调系统是一种旨在提升企业客户服务体验和运营效率的工具。该系统通过一系列智能化和自动化的功能,帮助企业与用户之间建立更加便捷、高效的沟通桥梁。 0x02 漏洞概述 微信公众平台无限回调系统 /user/ajax.php 接口存在SQL注入漏洞,未经身…

live555 rtsp服务器实战之doGetNextFrame

live555关于RTSP协议交互流程 live555的核心数据结构值之闭环双向链表 live555 rtsp服务器实战之createNewStreamSource live555 rtsp服务器实战之doGetNextFrame 注意&#xff1a;该篇文章可能有些绕&#xff0c;最好跟着文章追踪下源码&#xff0c;不了解源码可能就是天书…

windows docker nvidia wsl2

下载驱动(GeForce Experience里的也可以)https://www.nvidia.cn/Download/index.aspx 安装wsl2https://blog.csdn.net/qq_39942341/article/details/121512900?ops_request_misc%257B%2522request%255Fid%2522%253A%2522172122816816800227436617%2522%252C%2522scm%2522%253A…

mac M1 创建Mysql8.0容器

MySLQ8.0 拉取m1镜像 docker pull mysql:8.0创建挂载文件夹并且赋予权限 sudo chmod 777 /Users/zhao/software/dockerLocalData/mysql 创建容器并且挂载 docker run --name mysql_8 \-e MYSQL_ROOT_PASSWORDadmin \-v /Users/zhao/software/dockerLocalData/mysql/:/var/l…

CSS3实现提示工具的渐入渐出效果及CSS3动画简介

上一篇文章用CSS3实现了一个提示工具&#xff0c;本文介绍如何利用CSS3实现提示工具以渐入的方式呈现&#xff0c;以渐出的方式消失。 CSS3主要可以通过两个样式来实现动画效果&#xff1a;animation和transition。 其中&#xff0c;animation需要自己定义一组关键帧从而实现…

第十届能源材料与电力工程国际学术会议(ICEMEE 2024)

第十届能源材料与电力工程国际学术会议&#xff08;ICEMEE 2024) 2024 10th International Conference on Energy Materials and Electrical Engineering 重要信息 ICEMEE 2024已通过SPIE - The International Society for Optical Engineering (ISSN: 0277-786X)单独出版…

修改了mybatis的xml中的sql不重启服务器如何动态加载更新

目录 一、背景 二、注意 三、代码 四、使用示例 五、其他参考博客 一、背景 开发一个报表功能&#xff0c;好几百行sql&#xff0c;每次修改完想自测下都要重启服务器&#xff0c;启动一次服务器就要3分钟&#xff0c;重启10次就要半小时&#xff0c;耗不起时间呀。于是在…

Spring Security之安全异常处理

前言 在我们的安全框架中&#xff0c;不管是什么框架&#xff08;包括通过过滤器自定义&#xff09;都需要处理涉及安全相关的异常&#xff0c;例如&#xff1a;登录失败要跳转到登录页&#xff0c;访问权限不足要返回页面亦或是json。接下来&#xff0c;我们就看看Spring Sec…

公司政务办理流程分享(北京)

社保增减员&#xff1a; 参保登记——增减员业务这么办_北京市人力资源和社会保障局_社会保险 https://rsj.beijing.gov.cn/yltc/202310/t20231025_3287007.html 公积金增减员&#xff1a; https://dwwsyw.gjj.beijing.gov.cn/

CentOS 7 初始化环境配置详细

推荐使用xshell远程连接&#xff0c;如链接不上 请查看 CentOS 7 网络配置 修改主机名 hostname hostnamectl set-hostname xxx bash 关闭 SElinux 重启之后生效 配置yum源&#xff08;阿里&#xff09; 先备份CentOS-Base.repo&#xff0c;然后再下载 mv /etc/yum.repos…

ROS参数服务器理论模型

ROS参数服务器理论模型 参数服务器角色实现参数服务器流程参数可以使用的类型 参数服务器角色 参数服务器实现是最为简单的&#xff0c;该模型如下图所示,该模型中涉及到三个角色: ROS Master (管理者)Talker (参数设置者)Listener (参数调用者) 实现参数服务器流程 整个流…

Ubuntu 24.04安装Jellyfin媒体服务器图解教程

使用 Jellyfin 等开源软件创建媒体服务器肯定能帮助您管理和跨各种设备传输媒体集合。当你有一个封闭社区时&#xff0c;这尤其有用。 什么是 Jellyfin 媒体服务器&#xff1f; Jellyfin 媒体服务器&#xff0c;顾名思义&#xff0c;是一款开源软件&#xff0c;允许用户使用本…

等保-Linux等保测评

等保-Linux等保测评 1.查看相应文件&#xff0c;账户xiaoming的密码设定多久过期 rootdengbap:~# chage -l xiaoming Last password change : password must be changed Password expires : pass…

Ubuntu22.04安装CUDA+CUDNN+Conda+PyTorch

步骤&#xff1a; 1、安装显卡驱动&#xff1b; 2、安装CUDA&#xff1b; 3、安装CUDNN&#xff1b; 4、安装Conda&#xff1b; 5、安装Pytorch。 一、系统和硬件信息 1、Ubuntu 22.04 2、显卡&#xff1a;4060Ti 二、安装显卡驱动 &#xff08;已经安装的可以跳过&a…