【鸿蒙实战开发】基于原生能力的横竖屏旋转适配

104 篇文章 0 订阅
66 篇文章 0 订阅

往期知识点整理

场景描述

目前很多应用和场景需要用到横竖屏旋转,下面列举一些目前遇到的高频问题:

场景一:我们如何通过传感器自己感知方向,自己设置旋转;(使用sensor感知设备是不关心设备是否启用系统自带的旋转锁定)

场景二:在一个应用内,不同的页面有不同的旋转策略;如:首页仅竖屏,详情页面允许横竖屏切换;

概念说明:

本文的旋转策略是:旋转策略是指当前页面支持的设备旋转方向。

页面方向是:页面方向是手机的页面当前的显示方向。

场景一:

我们如何通过传感器自己感知方向,自己设置旋转;(使用sensor感知设备是不关心设备是否启用系统自带的旋转锁定)

效果图:

关键步骤:

第一步:感知方向;使用sensor感知设备的真实朝向。

// 1 原始数据(3维度)
sensor.on(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => {
let degree: number = -1;
let rotation: string = 'INVALID';
// 2 将三维的角度变二维
degree = CalDegree(data.x, data.y, data.z)
// 3 将角度转化到方向
if (degree >= 0 && (degree <= 30 || degree >= 330)) {
rotation = "ROTATION_0";
} else if (degree >= 60 && degree <= 120) { // Use ROTATION_90 when degree range is [60, 120]
rotation = "ROTATION_90";
} else if (degree >= 150 && degree <= 210) { // Use ROTATION_180 when degree range is [150, 210]
rotation = "ROTATION_180";
} else if (degree >= 240 && degree <= 300) { // Use ROTATION_270 when degree range is [240, 300]
rotation = "ROTATION_270";
}

第二步:设置旋转;

相关接口:setPreferredOrientation;设置窗口的显示方向属性

indow(getContext(this)).then((data) => {
          data.setPreferredOrientation(window.Orientation.LANDSCAPE_INVERTED)
        })

设置方向:

相关接口:

调用窗口的Orientation设置方向即可,具体的设置窗口的显示方向,属性设置参考下表;

UNSPECIFIED表示未定义方向模式,由系统判定。
PORTRAIT表示竖屏显示模式。
LANDSCAPE表示横屏显示模式。
PORTRAIT_INVERTED表示反向竖屏显示模式。
LANDSCAPE_INVERTED表示反向横屏显示模式。

场景二:

竖屏,允许横竖屏,仅竖屏,仅横屏;首页竖屏,进去就横屏。支持切换竖屏;给最外层组件设置旋转;

在一个应用内,不同的页面有不同的旋转策略;如,首页仅竖屏,详情页面允许横竖屏切换;

从横屏跳竖屏;两个页面不同的跳转;

效果图:

关键步骤:

第一步:在应用统一的位置注册无感监听;

第二步:建立页面与旋转方向的映射表;

第三步:结合全局埋点的能力,实现不同页面的旋转适配

说明:该映射表开发者可以根据实际的诉求使用从本地配置文件更新或者直接使用全局状态变量实现动态修改。

let pageOrientations: Record<string, window.Orientation> = {
  "Logon": window.Orientation.PORTRAIT,
  "Detail": window.Orientation.LANDSCAPE,
  "Page2": window.Orientation.PORTRAIT_INVERTED,
  "Page3": window.Orientation.LANDSCAPE_INVERTED,
}

第三步:根据映射表在无感监听的回调里控制旋转策略;

//判断是否为空 mainWindow
if (!windowName || windowName == 'mainWindow') {
  windowName = 'mainWindow'
}
let name = windowName as string
windows[name] = curWindow;

let myObserve = curWindow.getUIContext().getUIObserver();
mypagestack[name] = new Stack<pageTracking>();

// mypagestack.push <windowName, Stack<pageTracking>>
//监听navDestination组件生命周期变化
myObserve.on('navDestinationUpdate', (info) => {
  //映射成mypage
  let mypage = new MyPage
  mypage.id = info.navDestinationId
  mypage.name = info.name
  mypage.path = info.param?.toString()
  mypage.type = 'NavDestination'
  mypage.lifeCricle = info.state
  //
  tracking(mypage, name)

})
//监听page生命周期变化
myObserve.on('routerPageUpdate', (info) => {... })
}

//使用mypage埋点  存生命周期信息
function tracking(mypage: MyPage, windowname: string) {
  let stack: Stack<pageTracking> = mypagestack[windowname]
  // 1.存页面信息(abouttoappear),同时打印当前所有路径 打印当前栈的顺序
  // 如果当前栈元素为一个且当前元素为navd页面,仅修改对应页面的类型
  // 不入栈 ,而是将对应的栈顶元素的page类型改为navPage
  if (mypage.lifeCricle == 2) {...}
  // 2.更新页面信息 :onshown(刷新开始时间)
  else if (mypage.lifeCricle == 0) {
    // 改变方向:
    windows[windowname].setPreferredOrientation(pageOrientations[mypage.name as string])
  }
  // 3.更新页面信息 :onhidden(累计值 刷新停留时间)
  else if (mypage.lifeCricle == 1) {...}

  // 4.输出页面信息 abouttodistoappear 删除页面信息
  else if (mypage.lifeCricle == 3) {...}

}

场景三:

某些页面会存在设置临时方向,如视频竖屏转横屏;视屏播放临时方向的设置

接口:USER_ROTATION_LANDSCAPE;表示临时横屏后受开关控制和系统判定的自动旋转模式。

window.getLastWindow(getContext(this), (err, win) => {
  win.setPreferredOrientation(window.Orientation.USER_ROTATION_LANDSCAPE)
})

视频播放的过程中,用户可能在竖屏状态下,通过点击最大化按钮将视频变为横屏播放。该场景下要求手机的整体策略不变。

接口:USER_ROTATION_LANDSCAPE;表示临时横屏后受开关控制和系统判定的自动旋转模式。

window.getLastWindow(getContext(this), (err, win) => {
  win.setPreferredOrientation(window.Orientation.USER_ROTATION_LANDSCAPE)
})

视频播放的过程中,用户可能在竖屏状态下,通过点击最大化按钮将视频变为横屏播放。该场景下要求手机的整体策略不变。

其他常见问题:

Q1:如何感知系统的自动旋转开关:如果是开的,app页面内适配?

A:监听方法sensor模块 、seting info(单独get)

//1.传感器的监听方法sensor模块 (对应的回调一直触发,建议仅在需要的页面开启)
// 1 原始数据(3维度)
sensor.on(sensor.SensorId.GRAVITY, (data: sensor.GravityResponse) => {
  let degree: number = -1;
  let rotation: string = 'INVALID';
  // 2 3wei bian erwei
  degree = CalDegree(data.x, data.y, data.z)
  // 3 角度=》方向
  if (degree >= 0 && (degree <= 30 || degree >= 330)) {
    rotation = "ROTATION_0";
  } else if (degree >= 60 && degree <= 120) { // Use ROTATION_90 when degree range is [60, 120]
    rotation = "ROTATION_90";
  } else if (degree >= 150 && degree <= 210) { // Use ROTATION_180 when degree range is [150, 210]
    rotation = "ROTATION_180";
  } else if (degree >= 240 && degree <= 300) { // Use ROTATION_270 when degree range is [240, 300]
    rotation = "ROTATION_270";
  }
  // 4 设置方向
  // setxxxx
  console.log("QH- sensor.on" + rotation)
});
2.setings 模块只能获取不能监听
// 获取 控制中心的 自动旋转开关:值为1,表示启用;值为0,表示不启用。
settings.getValueSync(getContext(), settings.general.ACCELEROMETER_ROTATION_STATUS, '-1')

// 自动旋转关闭时,获取当前设备的方向:值为0,表示屏幕旋转0度;值为1,表示屏幕旋转90度;值为2,表示屏幕旋转180度;值为3,表示屏幕旋转270度
orientation = settings.getValueSync(getContext(), settings.display.DEFAULT_SCREEN_ROTATION, '-1')
console.log("QH- settings.getValueSync" + orientation)

总是有很多小伙伴反馈说:鸿蒙开发不知道学习哪些技术?不知道需要重点掌握哪些鸿蒙开发知识点? 为了解决大家这些学习烦恼。在这准备了一份很实用的鸿蒙全栈开发学习路线与学习文档给大家用来跟着学习。

针对一些列因素,整理了一套纯血版鸿蒙(HarmonyOS Next)全栈开发技术的学习路线,包含了鸿蒙开发必掌握的核心知识要点,内容有(OpenHarmony多媒体技术、Napi组件、OpenHarmony内核、OpenHarmony驱动开发、系统定制移植……等)技术知识点。

《鸿蒙 (Harmony OS)开发学习手册》(共计892页):https://gitcode.com/HarmonyOS_MN/733GH/overview

如何快速入门?

1.基本概念
2.构建第一个ArkTS应用
3.……

开发基础知识:

1.应用基础知识
2.配置文件
3.应用数据管理
4.应用安全管理
5.应用隐私保护
6.三方应用调用管控机制
7.资源分类与访问
8.学习ArkTS语言
9.……

在这里插入图片描述

基于ArkTS 开发

1.Ability开发
2.UI开发
3.公共事件与通知
4.窗口管理
5.媒体
6.安全
7.网络与链接
8.电话服务
9.数据管理
10.后台任务(Background Task)管理
11.设备管理
12.设备使用信息统计
13.DFX
14.国际化开发
15.折叠屏系列
16.……

在这里插入图片描述

鸿蒙开发面试真题(含参考答案):https://gitcode.com/HarmonyOS_MN/733GH/overview

在这里插入图片描述

OpenHarmony 开发环境搭建

图片

《OpenHarmony源码解析》:https://gitcode.com/HarmonyOS_MN/733GH/overview

  • 搭建开发环境
  • Windows 开发环境的搭建
  • Ubuntu 开发环境搭建
  • Linux 与 Windows 之间的文件共享
  • ……
  • 系统架构分析
  • 构建子系统
  • 启动流程
  • 子系统
  • 分布式任务调度子系统
  • 分布式通信子系统
  • 驱动子系统
  • ……

图片

OpenHarmony 设备开发学习手册:https://gitcode.com/HarmonyOS_MN/733GH/overview

图片

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值