鸿蒙一次开发,多端部署(二)从一个例子开始

本章通过一个天气应用,介绍一多应用的整体开发过程,包括UX设计、工程管理及调试、页面开发等。

UX设计

本示例中的天气应用包含主页、管理城市和添加城市三个页面,其中主页中又包含菜单和更新间隔两个弹窗,基本业务逻辑如下所示。

“一多”建议从最初的设计阶段开始就拉通多设备综合考虑。考虑实际智能终端设备种类繁多,设计师无法针对每种具体设备各自出一份UX设计图。“一多”建议从设备屏幕宽度的维度,将设备划分为四大类。设计师只需要针对这四大类设备做设计,而无需关心具体的设备形态。

设备类型屏幕宽度(vp)
超小设备[0, 320)
小设备[320, 600)
中设备[600, 840)
大设备[840, +∞)

说明:

  • vp是virtual pixel(虚拟像素)的缩写,是常用的长度单位,详见视觉基础小节中的介绍。
  • 此处基于设备屏幕宽度划分不同设备是为了读者方便理解。通常智能设备上的应用都是以全屏的形式运行,但随着移动技术的发展,当前部分智能设备支持应用以自由窗口模式运行(即用户可以通过拖拽等操作自由调整应用运行窗口的尺寸),故以应用窗口尺寸为基准进行划分更为合适,本文后续的响应式布局章节中将详细介绍相关内容。
  • OpenHarmony当前仅有默认设备和平板两种设备形态,IDE在创建OpenHarmony工程时也仅可以选择默认设备和平板。随着演进,其支持的设备形态会不断丰富,本文也会定期刷新相关介绍。

默认设备和平板对应于小设备、中设备及大设备,本示例以这三类设备场景为例,介绍不同设备上的UX设计。天气主页在不同设备上的设计图如下所示。

另外,大设备中天气主页还允许用户开启或者隐藏侧边栏。

从天气应用在各设备上的UX设计图中,可以观察到如下UX的一些“规律”:

  • 在不同的屏幕宽度下,应用的整体风格基本保持一致。
  • 在相近的屏幕宽度范围内,应用的布局基本不变;在不同的屏幕宽度范围内,应用的布局有较大差异。
  • 应用在小屏幕下显示的元素,是大屏幕中显示元素的子集。
    • 考虑到屏幕尺寸及显示效果,大屏幕中可以显示的元素数量一定不少于小屏幕。
    • 为充分利用屏幕尺寸优势,大屏幕可以有其独有的元素或设计(如本示例中的侧边栏)。

如此,既在各设备上体现了UX的一致性,也在各设备上体现了UX的差异性,从而既可以保障各设备上应用界面的体验,也可以最大程度复用界面代码。

在应用UX设计章节中,将详细介绍应用的UX设计规则。

工程管理及调试

在本文IDE使用章节中,将详细介绍一多的工程创建及管理等,本小节仅介绍最基础的工程创建及多设备预览调试。

工程创建

一多应用的工程创建过程,与传统应用并无较大差异。只需在工程创建过程中,注意在“Device Type”选项中勾选所有该应用期望运行的目标设备类型,保证后续该应用可以在所有目标设备上正确安装即可。

预览调试

在代码开发过程中,可以开启预览器,并打开“Multi-profile preview”开关,实时观察应用在不同设备下的表现。

特别的,还可以点击“+ New Profile”按钮,新增自定义预览器。

页面开发

天气应用中涉及较多的页面和弹窗,本小节以天气主页为例,简单介绍不同设备下的页面实现思路。

观察天气主页在不同设备上的UX设计图,可以进行如下设计:

  • 将天气主页划分为9个基础区域,如:

  • 基础区域9仅在大设备上显示,基础区域1-8虽然在各设备上始终展示但其尺寸及区域内的布局基本保持不变,可以结合自适应布局能力以自定义组件的形式分别实现这9个基础区域。

  • 基础区域1-8之间的布局在不同设备上有较大差异,可以使用响应式布局中的栅格布局能力实现组件间的布局效果。

  • 展开和隐藏侧边栏的功能可以通过侧边栏组件来实现。侧边栏是大设备上独有的,借助响应式布局中的媒体查询能力,控制仅在大设备上展示侧边栏即可。

主页基础区域

天气主页中的9个基础区域介绍及实现方案如下表所示。

编号简介实现方案
1标题栏自适应布局拉伸能力。
2天气概览Row和Column组件,并指定其子组件按照主轴起始方向对齐或居中对齐。
3每小时天气自适应布局延伸能力 。
4每日天气自适应布局延伸能力 。
5空气质量Canvas画布组件绘制空气质量图,并使用Row组件和Column组件控制内部元素的布局。
6生活指数自适应布局均分能力。
7日出日落Canvas画布组件绘制日出日落图 。
8应用信息Row和Column组件,并指定其子组件居中对齐。
9侧边导航栏综合运用自适应布局中的拉伸能力、占比能力和延伸能力 。

天气主页涉及的内容较多,因篇幅限制,本小节仅介绍区域3(每小时天气)的实现,读者可以自行查看开源代码,了解其它基础区域的实现。

延伸能力是指容器组件内的子组件,按照其在列表中的先后顺序,随容器组件尺寸变化显示或隐藏。随着可用显示区域的增加,用户可以看到的“每小时天气”信息也不断增加,故“每小时天气”可以通过延伸能力实现,其核心代码如下所示。

import { Forecast, getHoursData, MyDataSource, Style } from '@ohos/common';@Component
export default struct HoursWeather {private hoursData: Forecast[] = getHoursData(0);@State hoursDataResource: MyDataSource = new MyDataSource(this.hoursData);build() {// 通过列表组件实现延伸能力List() {LazyForEach(this.hoursDataResource, (hoursItem:IDataSource) => {ListItem() {// 具体每个小时的天气情况Column() { // ... }}})}.height(Style.CARD_HEIGHT).borderRadius(Style.NORMAL_RADIUS).backgroundColor(Style.CARD_BACKGROUND_COLOR)// 将列表方向设置为水平方向.listDirection(Axis.Horizontal)}
}

城市天气详情

天气主页右侧的城市天气详情由区域1-8组成,区域1(标题栏)始终固定在页面顶部,区域2-8在不同设备下的布局不同且可以随页面上下滚动。本小节介绍如何实现城市天气详情中区域2~8的布局效果。

设备屏幕可能无法一次性显示区域2-8的所有内容,故需要在外层增加滚动组件(即Scroll组件)以支持上下滚动。不同设备下区域2-8的相对位置一共有三套不同的布局,可以借助响应式布局中的栅格布局实现这一效果。本示例中将栅格在不同场景下分别划分为4列、8列和12列,区域2-8在不同场景下的布局如下表所示。

说明: 为提升用户体验,大设备侧边栏隐藏状态下,每日天气与空气质量的相对顺序发生了改变。可以调整通过GridCol栅格子组件的order属性,实现目标效果。

import AirQuality from './AirQuality'; //组件请参考相关实例
import HoursWeather from './HoursWeather';
import IndexHeader from './IndexHeader';
import IndexEnd from './IndexEnd';
import LifeIndex from './LifeIndex';
import MultidayWeather from './MultidayWeather';
import SunCanvas from './SunCanvas';
import { CityListData, Style } from '@ohos/common';@Component
export default struct HomeContent {private cityListData: CityListData | undefined = undefined;private index: number = 1;@Prop showSideBar: boolean;@State headerOpacity: number = 1;build() {// 支持滚动Scroll() {GridRow({columns: { sm: 4, md: 8, lg: this.showSideBar ? 8 : 12 },gutter: { x: Style.GRID_GUTTER, y: Style.GRID_GUTTER },breakpoints: { reference: BreakpointsReference.WindowSize } }) {// 天气概览GridCol({ span: { sm: 4, md: 8, lg: this.showSideBar ? 8 : 12 }, order: 1 }) {IndexHeader({ headerDate: this.cityListData.header, index: this.index }).opacity(this.headerOpacity)}// 每小时天气GridCol({ span: { sm: 4, md: 8, lg: 8 }, order: 2 }) {HoursWeather({ hoursData: this.cityListData.hoursData })}// 每日天气GridCol({ span: 4, order: {sm: 3, md: 3, lg: this.showSideBar ? 3 : 4} }) {MultidayWeather({ weekData: this.cityListData.weekData })}// 空气质量GridCol({ span: 4, order: {sm: 4, md: 4, lg: this.showSideBar ? 4 : 3} }) {AirQuality({ airData: this.cityListData.airData, airIndexData: this.cityListData.airIndex })}// 生活指数GridCol({ span: 4, order: 5 }) {LifeIndex({ lifeData: this.cityListData.suitDate })}// 日出日落GridCol({ span: 4, order: 6 }) {SunCanvas()}// 应用信息GridCol({ span: { sm: 4, md: 8, lg: this.showSideBar ? 8 : 12 }, order: 7 }) {IndexEnd()}}}.width('100%')}
}

主页整体实现

综合考虑各设备下的效果,天气主页的根节点使用侧边栏组件:

  • 小设备和中设备既不展示侧边栏,也不提供控制侧边栏显示和隐藏的按钮。
  • 大设备默认展示侧边栏,同时提供控制侧边栏显示和隐藏的按钮。

另外主页右侧的城市天气详情,支持左右滑动切换城市,可以使用Swiper组件实现目标效果。

  • 小设备和中设备开启Swiper组件的导航点,引导用户通过左右滑动切换不同城市。
  • 大设备中用户通过点击侧边栏中的城市列表即可高效的切换不同城市,此时需要关闭Swiper组件的导航点。
import HomeContent from './home/HomeContent'; //组件请参考相关实例
import IndexTitleBar from './home/IndexTitleBar';
import SideContent from './home/SideContent';
import { CityListData,  getCityListWeatherData } from '@ohos/common';@Entry
@Component
struct Home {@State cityListWeatherData: CityListData[] = getCityListWeatherData();@State curBp: string = 'md';@State showSideBar: boolean = false;build() {SideBarContainer(SideBarContainerType.Embed) {// 左侧侧边栏SideContent({ showSideBar: $showSideBar })// 右侧内容区Flex({direction: FlexDirection.Column}) {// 基础区域1标题栏IndexTitleBar({ curBp: this.curBp, showSideBar: $showSideBar }).height(56)// 天气详情,通过Swiper组件实现左右滑动切换城市的效果Swiper() {ForEach(this.cityListWeatherData, (item:CityListData, index) => {HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })})}// 大设备关闭导航点.indicator(this.curBp !== 'lg').width('100%')}}.height('100%').sideBarWidth('33.3%')// 通过状态变量,控制不同设备下侧边栏的显隐状态.showSideBar(this.showSideBar)}
}

最终,天气首页的运行效果如下图所示。

功能开发

应用开发不仅包含应用页面开发,还包括应用后端功能开发以及服务器端开发等。服务器端开发不在本文的讨论范围内,本小节仅介绍多设备上应用功能开发的注意事项。

如前文所示,本示例的目标运行设备是小设备、中设备和大设备,对应实际的设备类型为默认设备和平板等。这些设备运行的都是标准系统,其系统能力一致,所以无需做特别考虑。但是在超小设备(对应的实际设备类型为智能穿戴设备等)上,考虑CPU、内存、硬盘等硬件限制,往往会对系统进行裁剪。如果在应用后端功能开发时调用当前系统没有的能力,就可能会引发异常。

通常有两种方式解决上述问题:

  • 在应用安装包中描述其需要的系统能力,保证本应用仅被分发和安装到可以满足其诉求的系统中。
  • 在使用特定系统能力前,通过canIUse接口判断系统能力是否存在,进而执行不同的逻辑。

相关实例

针对天气应用,有以下相关实例可供参考:

天气应用:天气应用示例

为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05

《鸿蒙开发学习手册》:

如何快速入门:https://qr21.cn/FV7h05

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

开发基础知识:https://qr21.cn/FV7h05

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

基于ArkTS 开发:https://qr21.cn/FV7h05

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

鸿蒙开发面试真题(含参考答案):https://qr18.cn/F781PH

鸿蒙开发面试大盘集篇(共计319页):https://qr18.cn/F781PH

1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向

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

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

相关文章

Aztec的客户端证明

1. 引言 隐私保护 zk-rollup 的证明生成与通用 zk-rollup 的证明生成有很大不同。原因是给定交易中存在特定数据(由私有函数处理),我们希望保持完全私有。在本文中,我们探讨了用于证明私有函数正确执行的客户端证明生成&#xff…

arm-linux实现onvif server+WS-UsernameToken令牌验证

目录 一、环境搭建 1、安装openssl 2、安装bison 3、安装flex 二、gsoap下载 三、编译x86版本gsoap 四、编译arm-linux版本gsoap 1、交叉编译openssl 1.1、下载openssl 1.2、交叉编译 2、交叉编译zlib 2.1、下载zlib 2.2、交叉编译 3、交叉编译gsoap 3.1、编译过…

【嵌入式学习】Qtday03.21

一、思维导图 二、练习 自由发挥登录窗口的应用场景,实现一个登录窗口界面。(不要使用课堂上的图片和代码,自己发挥,有利于后面项目的完成) 要求: 1. 需要使用Ui界面文件进行界面设计 2. ui界面上的组件…

深入了解 Spring boot的事务管理机制:掌握 Spring 事务的几种传播行为、隔离级别和回滚机制,理解 AOP 在事务管理中的应用

🎉🎉欢迎光临,终于等到你啦🎉🎉 🏅我是苏泽,一位对技术充满热情的探索者和分享者。🚀🚀 🌟持续更新的专栏《Spring 狂野之旅:从入门到入魔》 &a…

LeetCode 热题 100 | 堆(一)

目录 1 什么是堆排序 1.1 什么是堆 1.2 如何构建堆 1.3 举例说明 2 215. 数组中的第 K 个最大元素 2.1 子树大根化 2.2 遍历所有子树 2.3 弹出栈顶元素 2.4 完整代码 菜鸟做题,语言是 C 1 什么是堆排序 1.1 什么是堆 堆的定义和分类&#xff…

【c++入门】命名空间,缺省参数与函数重载

🔥个人主页: Quitecoder 🔥专栏:c笔记仓 朋友们大家好!本篇内容我们进入一个新的阶段,进入c的学习!希望我的博客内容能对你有帮助! 目录 1.c关键字2.第一个c代码3.命名空间3.1 nam…

CTF-辨别细菌

题目描述&#xff1a;try your best to find the flag. 进入靶场后发现是一个游戏&#xff0c;需要全部答对才可以得到最后的flag 查看了一下源码&#xff0c;发现有一个答案模板的模块 尝试解释一下代码 <!-- 答案模版 --> <script id"template_game_pi…

数据结构/C++:红黑树

数据结构/C&#xff1a;红黑树 概念实现基本结构插入uncle为红色节点uncle为黑色节点 总代码展示 概念 红黑树是一种二叉搜索树&#xff0c;一般的二叉搜索会发生不平衡现象&#xff0c;导致搜索效率下降&#xff0c;于是学者们开始探索如何让二叉搜索树保持平衡&#xff0c;这…

Agent驱动的RPA——实在Agent(智能体):自动化时代的新引擎

随着人工智能和机器学习技术的快速发展&#xff0c;智能Agent在 RPA领域扮演了革命性的角色。 Agent驱动的RPA不仅实现了传统规则导向自动化工具的功能升级&#xff0c;而且通过引入自主、智能决策与协作能力&#xff0c;为现代企业带来了更高程度的灵活性与智能化水平。随着数…

第1章 计算机系统概述

王道学习 1.1 操作系统的基本概念 1.1.1 操作系统的概念 1.1.2 操作系统的特征 操作系统是一种系统软件&#xff0c;但与其他系统软件和应用软件有很大的不同&#xff0c;它有自己的特殊性即基本特征。操作系统的基本特征包括并发、共享、虚拟和异步。这些概念对理解和掌握…

kail linux破解密码--- 详细过程(配合图文让你看了就会)

1.准备工作 1.vmware虚拟机 2.kali的系统 3.无线网卡一张(这个是必须的我买的是30多块) 4.这里为了实验&#xff0c;和直观的看到效果&#xff0c;用手机开了一个wifi然后使用kali进行破解 2.下载kali然后安装到虚拟机vmware 直接在官网下载 Get Kali | Kali Linux 我选…

WebXR实践——利用aframe框架浏览器展示全景图片

一、效果 话不多说&#xff0c;先上效果 二、代码 index.html <!DOCTYPE html> <html><head><meta charset"utf-8"><title>360&deg; Image</title><meta name"description" content"360&deg; Imag…

【机器学习】深入解析线性回归模型

&#x1f388;个人主页&#xff1a;豌豆射手^ &#x1f389;欢迎 &#x1f44d;点赞✍评论⭐收藏 &#x1f917;收录专栏&#xff1a;机器学习 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共同学习、交流进…

高精度铸铁平台制造工艺有多精细——河北北重机械

高精度铸铁平台制造工艺通常包括以下几个步骤&#xff1a; 材料准备&#xff1a;选择合适的铸铁材料&#xff0c;并确保其质量符合要求。常用的铸铁材料包括灰铸铁、球墨铸铁等。 模具制造&#xff1a;根据平台的设计要求&#xff0c;制造适用的模具。模具一般由砂型、金属模具…

【python】flask基于cookie和session来实现会话控制

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

【开源-土拨鼠充电系统】鸿蒙 HarmonyOS 4.0 App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在Gitee或GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍Gitee开源项目地址&#x1f449;&#xff1a;https://gitee.com/cheinlu/groundhog-charging…

力扣Lc19--- 268. 丢失的数字(java版)-2024年3月20日

1.题目描述 2.知识点 &#xff08;1&#xff09;比如数组里面有n个数&#xff0c;然后计算这n个数的总和(用等差求和数列计算&#xff09;,然后减去数组的和&#xff0c;用总和减去数组和即为所得 &#xff08;2&#xff09;加强型 for 循环&#xff08;也称为 for-each 循环&…

单片机--数电(4)

触发器 数字电路中&#xff1a;分组合逻辑电路与时序逻辑电路两大类 组合逻辑电路的基本单元是门电路&#xff08;与或非等一些门电路&#xff09; 时序逻辑电路的基本单元是触发器 触发器与门电路的区别 门电路某一时刻的输出信号完全取决于该时刻的输入信号&#xff0c;…

销售数据分析怎么做?用好这5个数据分析方法与模型就足够了。

企业经营其实简单来说就是做买卖&#xff0c;有了买卖自然就产生了销售数据&#xff0c;那怎么能让这些销售数据产生价值呢&#xff1f;答案就是数据分析。通过对销售数据的分析&#xff0c;可以帮助企业及时洞察市场动向&#xff0c;发现企业销售过程中的问题&#xff0c;调整…

ResNet《Deep Residual Learning for Image Recognition》

ResNet论文学习 引言Deep Residual Learning 深度残差学习网络结构 总结代码复现 引言 深度网络自然地以端到端的多层方式集成低/中/高级特征和分类器&#xff0c;特征的“级别”可通过堆叠层的数量来丰富 随着网络层数加深&#xff0c;提取的特征越强&#xff0c;但是 网络…