网站安全漏洞扫描工具,怎么只做自己的电商网站,网站维护 收录,金华建设局政务网站系列文章目录
HarmonyOS Next 系列之省市区弹窗选择器实现#xff08;一#xff09; HarmonyOS Next 系列之验证码输入组件实现#xff08;二#xff09; HarmonyOS Next 系列之底部标签栏TabBar实现#xff08;三#xff09; HarmonyOS Next 系列之HTTP请求封装和Token…系列文章目录
HarmonyOS Next 系列之省市区弹窗选择器实现一 HarmonyOS Next 系列之验证码输入组件实现二 HarmonyOS Next 系列之底部标签栏TabBar实现三 HarmonyOS Next 系列之HTTP请求封装和Token持久化存储四 HarmonyOS Next 系列之从手机选择图片或拍照上传功能实现五 HarmonyOS Next 系列之可移动悬浮按钮实现六 文章目录 系列文章目录前言一、实现原理分析二、API简单回顾三、规避和限制移动范围四、窗口宽高、状态栏高度、底部规避区域高度获取1、窗口宽高获取2、状态栏高度获取2、底部规避区域高度获取 四、完整代码实现五、其他说明 前言
HarmonyOS Next基于API11实现一个可移动的悬浮按钮
ps为演示作用这边和后续代码例子随便用回到顶部图标来做演示实际可自定义替换 一、实现原理分析
1、布局方面使用Stack容器让悬浮按钮堆叠在页面之上通过postion属性x,y设置悬浮按钮位置x,y为相对页面左上角距离 2、事件处理在移动过程中通过监听touch事件获取手指在屏幕上位置与初始触摸点位置比较计算悬浮按钮的偏移量动态更新悬浮按钮x,y值。
二、API简单回顾
touch触摸事件
1、触摸类型TouchType
名称描述Down手指按下时触发。Up手指抬起时触发。Move手指按压态在屏幕上移动时触发。
2、手指信息TouchObject
名称描述type触摸事件的类型windowX触摸点相对于应用窗口左上角的X坐标。windowY触摸点相对于应用窗口左上角的Y坐标。
说明以x轴为例计算两个触摸点(A、B)水平方向距离只需B.windowX-A.windowX而在我们实现悬浮按钮处理过程中这个A点就是手指刚按下去触摸点的windowXB点就是移动过程中触摸点的windowX在移动过程中不断计算这个差值后更新悬浮按钮坐标就能让其跟着手指移动。当然在这个过程中还需要考虑悬浮按钮移出屏幕情况需要规避和限制。
pswindowX、windowY单位为vp 三、规避和限制移动范围
为了让悬浮按钮不移出屏幕需要限制x、y大小 最小值很容易想到x0,y0也即悬浮按钮在最左上角
最大值位置在页面右下角 假设悬浮按钮半径为R窗口宽为winWidth、窗口高winHeight状态栏高statusHeight,底部规避区域高bottomHeight
x最大值winWidth-2R y最大值winHeight-2R-statusHeight-bottomHeight 所以x范围为0~winWidth-2Ry范围0 ~winHeight-2R-statusHeight-bottomHeight 四、窗口宽高、状态栏高度、底部规避区域高度获取
1、窗口宽高获取
import { window } from kit.ArkUI
.....
.....
.....window.getLastWindow(getContext(this), (err, windowClass) {if (!err.code) {//获取窗口宽高let windowProperties windowClass.getWindowProperties()this.winWidth px2vp(windowProperties.windowRect.width)this.winHeight px2vp(windowProperties.windowRect.height)}})2、状态栏高度获取
import { window } from kit.ArkUI
.....
.....
.....window.getLastWindow(getContext(this), (err, windowClass) {if (!err.code) {//获取状态栏高度this.statusHeight px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)}})2、底部规避区域高度获取
import { window } from kit.ArkUI
.....
.....
.....
window.getLastWindow(getContext(this), (err, windowClass) {if (!err.code) {//获取手机底部规避区域高度this.bottomAvoidAreaHeight px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height)}})ps:需要注意的是上述获取到的宽高单位都是px需要统一转成vp单位方便和windowXY进行计算
四、完整代码实现
SuspensionButton .ets
import { window } from kit.ArkUIEntry
Component
struct SuspensionButton {State statusHeight: number 0 //状态栏高度State bottomAvoidAreaHeight: number 0 //手机底部规避区域高度State curLeft: number 0 //当前悬浮按钮距离窗口左边距离State curTop: number 0 //当前悬浮按钮距离窗口顶部距离private startLeft: number 0 //开始移动那一刻悬浮按钮距离窗口左边距离private startTop: number 0 //开始移动那一刻悬浮按钮距离窗口顶部距离private startX: number 0 //开始移动触摸点x坐标相对窗口左上角private startY: number 0 //开始移动触摸点y坐标相对窗口左上角private radius: number 25 //悬浮按钮半径单位vpprivate winWidth: number 0 //窗口宽度private winHeight: number 0 //窗口高度aboutToAppear() {this.getWindowInfo()}//获取窗口尺寸信息getWindowInfo() {window.getLastWindow(getContext(this), (err, windowClass) {if (!err.code) {//状态栏高度this.statusHeight px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM).topRect.height)//获取手机底部规避区域高度this.bottomAvoidAreaHeight px2vp(windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR).bottomRect.height)//获取窗口宽高let windowProperties windowClass.getWindowProperties()this.winWidth px2vp(windowProperties.windowRect.width)this.winHeight px2vp(windowProperties.windowRect.height)//设置初始位置位于屏幕右下角演示设置可根据实际调整this.curLeftthis.winWidth*0.8this.curTopthis.winHeight*0.8}})}build() {Stack() {Column(){//页面内容}.width(100%).height(100%)//悬浮按钮Row() {Image($r(app.media.top)).width(25)}.width(this.radius * 2).height(this.radius * 2).justifyContent(FlexAlign.Center).borderRadius(this.radius).backgroundColor(#E8E8E8).position({x: this.curLeft,y: this.curTop}).onTouch((event: TouchEvent) {//手指按下记录初始触摸点坐标、悬浮按钮位置if (event.type TouchType.Down) {this.startX event.touches[0].windowXthis.startY event.touches[0].windowYthis.startLeft this.curLeftthis.startTop this.curTop}//手指拖动else if (event.type TouchType.Move) {let touch event.touches[0]//计算悬浮球与左边距离x坐标 当前悬浮球距离左边开始位置(x轴)当前触摸点x坐标-开始移动触摸点x坐标let curLeft this.startLeft (touch.windowX - this.startX)//限制悬浮球不能移除屏幕左边curLeft Math.max(0, curLeft)//限制悬浮球不能移除屏幕右边this.curLeft Math.min(this.winWidth - 2 * this.radius, curLeft)//计算悬浮球与顶部距离y坐标 当前悬浮球距离顶部开始位置(y轴)当前触摸点y坐标-开始移动触摸点y坐标let curTop this.startTop (touch.windowY - this.startY)//限制悬浮球不能移除屏幕上边curTop Math.max(0, curTop)//限制悬浮球不能移除屏幕下边this.curTop Math.min(this.winHeight - 2 * this.radius - this.bottomAvoidAreaHeight - this.statusHeight, curTop)}})}.width(100%).height(100%).backgroundColor(#f2f2f2)}
}
运行效果
五、其他说明
如果是想实现悬浮窗原理也一样只不过把悬浮按钮半径计算拆开为x,y2个方向根据悬浮窗宽高替换带入计算即可。 如果想实现不可移动悬浮按钮类似案例中回到顶部固定在页面右下角只需要把触摸事件去掉即可。