從一個(gè)例子開始
本章通過一個(gè)天氣應(yīng)用,介紹一多應(yīng)用的整體開發(fā)過程,包括UX設(shè)計(jì)、工程管理及調(diào)試、頁面開發(fā)等。
UX設(shè)計(jì)
本示例中的天氣應(yīng)用包含主頁、管理城市和添加城市三個(gè)頁面,其中主頁中又包含菜單和更新間隔兩個(gè)彈窗,基本業(yè)務(wù)邏輯如下所示。
“一多”建議從最初的設(shè)計(jì)階段開始就拉通多設(shè)備綜合考慮。考慮實(shí)際智能終端設(shè)備種類繁多,設(shè)計(jì)師無法針對(duì)每種具體設(shè)備各自出一份UX設(shè)計(jì)圖。“一多”建議從設(shè)備屏幕寬度的維度,將設(shè)備劃分為四大類。設(shè)計(jì)師只需要針對(duì)這四大類設(shè)備做設(shè)計(jì),而無需關(guān)心具體的設(shè)備形態(tài)。
設(shè)備類型 | 屏幕寬度(vp) |
---|---|
超小設(shè)備 | [0, 320) |
小設(shè)備 | [320, 600) |
中設(shè)備 | [600, 840) |
大設(shè)備 | [840, +∞) |
說明:
開發(fā)前請(qǐng)熟悉鴻蒙開發(fā)指導(dǎo)文檔:[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
- vp是virtual pixel(虛擬像素)的縮寫,是常用的長度單位,詳見[視覺基礎(chǔ)]小節(jié)中的介紹。
- 此處基于設(shè)備屏幕寬度劃分不同設(shè)備是為了方便理解。通常智能設(shè)備上的應(yīng)用都是以全屏的形式運(yùn)行,但隨著移動(dòng)技術(shù)的發(fā)展,當(dāng)前部分智能設(shè)備支持應(yīng)用以自由窗口模式運(yùn)行(即用戶可以通過拖拽等操作自由調(diào)整應(yīng)用運(yùn)行窗口的尺寸),故以應(yīng)用窗口尺寸為基準(zhǔn)進(jìn)行劃分更為合適,本文后續(xù)的響應(yīng)式布局章節(jié)中將詳細(xì)介紹相關(guān)內(nèi)容。
- OpenHarmony當(dāng)前僅有默認(rèn)設(shè)備和平板兩種設(shè)備形態(tài),IDE在創(chuàng)建OpenHarmony工程時(shí)也僅可以選擇默認(rèn)設(shè)備和平板。隨著演進(jìn),其支持的設(shè)備形態(tài)會(huì)不斷豐富,本文也會(huì)定期刷新相關(guān)介紹。
默認(rèn)設(shè)備和平板對(duì)應(yīng)于小設(shè)備、中設(shè)備及大設(shè)備,本示例以這三類設(shè)備場景為例,介紹不同設(shè)備上的UX設(shè)計(jì)。天氣主頁在不同設(shè)備上的設(shè)計(jì)圖如下所示。
另外,大設(shè)備中天氣主頁還允許用戶開啟或者隱藏側(cè)邊欄。
從天氣應(yīng)用在各設(shè)備上的UX設(shè)計(jì)圖中,可以觀察到如下UX的一些“規(guī)律”:
- 在不同的屏幕寬度下,應(yīng)用的整體風(fēng)格基本保持一致。
- 在相近的屏幕寬度范圍內(nèi),應(yīng)用的布局基本不變;在不同的屏幕寬度范圍內(nèi),應(yīng)用的布局有較大差異。
- 應(yīng)用在小屏幕下顯示的元素,是大屏幕中顯示元素的子集。
- 考慮到屏幕尺寸及顯示效果,大屏幕中可以顯示的元素?cái)?shù)量一定不少于小屏幕。
- 為充分利用屏幕尺寸優(yōu)勢,大屏幕可以有其獨(dú)有的元素或設(shè)計(jì)(如本示例中的側(cè)邊欄)。
如此,既在各設(shè)備上體現(xiàn)了UX的一致性,也在各設(shè)備上體現(xiàn)了UX的差異性,從而既可以保障各設(shè)備上應(yīng)用界面的體驗(yàn),也可以最大程度復(fù)用界面代碼。
在[應(yīng)用UX設(shè)計(jì)章節(jié)]中,將詳細(xì)介紹應(yīng)用的UX設(shè)計(jì)規(guī)則。
工程管理及調(diào)試
在本文IDE使用章節(jié)中,將詳細(xì)介紹一多的工程創(chuàng)建及管理等,本小節(jié)僅介紹最基礎(chǔ)的工程創(chuàng)建及多設(shè)備預(yù)覽調(diào)試。
工程創(chuàng)建
一多應(yīng)用的工程創(chuàng)建過程,與傳統(tǒng)應(yīng)用并無較大差異。只需在工程創(chuàng)建過程中,注意在“Device Type”選項(xiàng)中勾選所有該應(yīng)用期望運(yùn)行的目標(biāo)設(shè)備類型,保證后續(xù)該應(yīng)用可以在所有目標(biāo)設(shè)備上正確安裝即可。
預(yù)覽調(diào)試
在代碼開發(fā)過程中,可以開啟預(yù)覽器,并打開“Multi-profile preview”開關(guān),實(shí)時(shí)觀察應(yīng)用在不同設(shè)備下的表現(xiàn)。
特別的,還可以點(diǎn)擊“+ New Profile”按鈕,新增自定義預(yù)覽器。
頁面開發(fā)
天氣應(yīng)用中涉及較多的頁面和彈窗,本小節(jié)以天氣主頁為例,簡單介紹不同設(shè)備下的頁面實(shí)現(xiàn)思路。
觀察天氣主頁在不同設(shè)備上的UX設(shè)計(jì)圖,可以進(jìn)行如下設(shè)計(jì):
- 將天氣主頁劃分為9個(gè)基礎(chǔ)區(qū)域,如:
- 基礎(chǔ)區(qū)域9僅在大設(shè)備上顯示,基礎(chǔ)區(qū)域1-8雖然在各設(shè)備上始終展示但其尺寸及區(qū)域內(nèi)的布局基本保持不變,可以結(jié)合[自適應(yīng)布局]能力以[自定義組件]的形式分別實(shí)現(xiàn)這9個(gè)基礎(chǔ)區(qū)域。
- 基礎(chǔ)區(qū)域1-8之間的布局在不同設(shè)備上有較大差異,可以使用響應(yīng)式布局中的[柵格布局]能力實(shí)現(xiàn)組件間的布局效果。
- 展開和隱藏側(cè)邊欄的功能可以通過[側(cè)邊欄組件]來實(shí)現(xiàn)。側(cè)邊欄是大設(shè)備上獨(dú)有的,借助響應(yīng)式布局中的[媒體查詢]能力,控制僅在大設(shè)備上展示側(cè)邊欄即可。
主頁基礎(chǔ)區(qū)域
天氣主頁中的9個(gè)基礎(chǔ)區(qū)域介紹及實(shí)現(xiàn)方案如下表所示。
編號(hào) | 簡介 | 實(shí)現(xiàn)方案 |
---|---|---|
1 | 標(biāo)題欄 | 自適應(yīng)布局拉伸能力。 |
2 | 天氣概覽 | Row和Column組件,并指定其子組件按照主軸起始方向?qū)R或居中對(duì)齊。 |
3 | 每小時(shí)天氣 | 自適應(yīng)布局延伸能力 。 |
4 | 每日天氣 | 自適應(yīng)布局延伸能力 。 |
5 | 空氣質(zhì)量 | Canvas畫布組件繪制空氣質(zhì)量圖,并使用Row組件和Column組件控制內(nèi)部元素的布局。 |
6 | 生活指數(shù) | 自適應(yīng)布局均分能力。 |
7 | 日出日落 | Canvas畫布組件繪制日出日落圖 。 |
8 | 應(yīng)用信息 | Row和Column組件,并指定其子組件居中對(duì)齊。 |
9 | 側(cè)邊導(dǎo)航欄 | 綜合運(yùn)用自適應(yīng)布局中的拉伸能力、占比能力和延伸能力 。 |
天氣主頁涉及的內(nèi)容較多,因篇幅限制,本小節(jié)僅介紹區(qū)域3(每小時(shí)天氣)的實(shí)現(xiàn),讀者可以自行查看開源代碼,了解其它基礎(chǔ)區(qū)域的實(shí)現(xiàn)。
延伸能力是指容器組件內(nèi)的子組件,按照其在列表中的先后順序,隨容器組件尺寸變化顯示或隱藏。隨著可用顯示區(qū)域的增加,用戶可以看到的“每小時(shí)天氣”信息也不斷增加,故“每小時(shí)天氣”可以通過延伸能力實(shí)現(xiàn),其核心代碼如下所示。
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() {
// 通過列表組件實(shí)現(xiàn)延伸能力
List() {
LazyForEach(this.hoursDataResource, (hoursItem:IDataSource) = > {
ListItem() {
// 具體每個(gè)小時(shí)的天氣情況
Column() {
// ...
}
}
})
}
.height(Style.CARD_HEIGHT)
.borderRadius(Style.NORMAL_RADIUS)
.backgroundColor(Style.CARD_BACKGROUND_COLOR)
// 將列表方向設(shè)置為水平方向
.listDirection(Axis.Horizontal)
}
}
城市天氣詳情
天氣主頁右側(cè)的城市天氣詳情由區(qū)域1-8組成,區(qū)域1(標(biāo)題欄)始終固定在頁面頂部,區(qū)域2-8在不同設(shè)備下的布局不同且可以隨頁面上下滾動(dòng)。本小節(jié)介紹如何實(shí)現(xiàn)城市天氣詳情中區(qū)域2~8的布局效果。
設(shè)備屏幕可能無法一次性顯示區(qū)域2-8的所有內(nèi)容,故需要在外層增加滾動(dòng)組件(即Scroll組件)以支持上下滾動(dòng)。不同設(shè)備下區(qū)域2-8的相對(duì)位置一共有三套不同的布局,可以借助響應(yīng)式布局中的[柵格布局]實(shí)現(xiàn)這一效果。本示例中將柵格在不同場景下分別劃分為4列、8列和12列,區(qū)域2-8在不同場景下的布局如下表所示。
說明: 為提升用戶體驗(yàn),大設(shè)備側(cè)邊欄隱藏狀態(tài)下,每日天氣與空氣質(zhì)量的相對(duì)順序發(fā)生了改變。可以調(diào)整通過GridCol柵格子組件的order屬性,實(shí)現(xiàn)目標(biāo)效果。
import AirQuality from './AirQuality'; //組件請(qǐng)參考相關(guān)實(shí)例
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() {
// 支持滾動(dòng)
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)
}
// 每小時(shí)天氣
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 })
}
// 空氣質(zhì)量
GridCol({ span: 4, order: {sm: 4, md: 4, lg: this.showSideBar ? 4 : 3} }) {
AirQuality({ airData: this.cityListData.airData, airIndexData: this.cityListData.airIndex })
}
// 生活指數(shù)
GridCol({ span: 4, order: 5 }) {
LifeIndex({ lifeData: this.cityListData.suitDate })
}
// 日出日落
GridCol({ span: 4, order: 6 }) {
SunCanvas()
}
// 應(yīng)用信息
GridCol({ span: { sm: 4, md: 8, lg: this.showSideBar ? 8 : 12 }, order: 7 }) {
IndexEnd()
}
}
}
.width('100%')
}
}
主頁整體實(shí)現(xiàn)
綜合考慮各設(shè)備下的效果,天氣主頁的根節(jié)點(diǎn)使用側(cè)邊欄組件:
- 小設(shè)備和中設(shè)備既不展示側(cè)邊欄,也不提供控制側(cè)邊欄顯示和隱藏的按鈕。
- 大設(shè)備默認(rèn)展示側(cè)邊欄,同時(shí)提供控制側(cè)邊欄顯示和隱藏的按鈕。
另外主頁右側(cè)的城市天氣詳情,支持左右滑動(dòng)切換城市,可以使用Swiper組件實(shí)現(xiàn)目標(biāo)效果。
- 小設(shè)備和中設(shè)備開啟Swiper組件的導(dǎo)航點(diǎn),引導(dǎo)用戶通過左右滑動(dòng)切換不同城市。
- 大設(shè)備中用戶通過點(diǎn)擊側(cè)邊欄中的城市列表即可高效的切換不同城市,此時(shí)需要關(guān)閉Swiper組件的導(dǎo)航點(diǎn)。
import HomeContent from './home/HomeContent'; //組件請(qǐng)參考相關(guān)實(shí)例
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) {
// 左側(cè)側(cè)邊欄
SideContent({ showSideBar: $showSideBar })
// 右側(cè)內(nèi)容區(qū)
Flex({direction: FlexDirection.Column}) {
// 基礎(chǔ)區(qū)域1標(biāo)題欄
IndexTitleBar({ curBp: this.curBp, showSideBar: $showSideBar })
.height(56)
// 天氣詳情,通過Swiper組件實(shí)現(xiàn)左右滑動(dòng)切換城市的效果
Swiper() {
ForEach(this.cityListWeatherData, (item:CityListData, index) = > {
HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })
})
}
// 大設(shè)備關(guān)閉導(dǎo)航點(diǎn)
.indicator(this.curBp !== 'lg')
.width('100%')
}
}
.height('100%')
.sideBarWidth('33.3%')
// 通過狀態(tài)變量,控制不同設(shè)備下側(cè)邊欄的顯隱狀態(tài)
.showSideBar(this.showSideBar)
}
}
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
最終,天氣首頁的運(yùn)行效果如下圖所示。
功能開發(fā)
應(yīng)用開發(fā)不僅包含應(yīng)用頁面開發(fā),還包括應(yīng)用后端功能開發(fā)以及服務(wù)器端開發(fā)等。服務(wù)器端開發(fā)不在本文的討論范圍內(nèi),本小節(jié)僅介紹多設(shè)備上應(yīng)用功能開發(fā)的注意事項(xiàng)。
如前文所示,本示例的目標(biāo)運(yùn)行設(shè)備是小設(shè)備、中設(shè)備和大設(shè)備,對(duì)應(yīng)實(shí)際的設(shè)備類型為默認(rèn)設(shè)備和平板等。這些設(shè)備運(yùn)行的都是標(biāo)準(zhǔn)系統(tǒng),其系統(tǒng)能力一致,所以無需做特別考慮。但是在超小設(shè)備(對(duì)應(yīng)的實(shí)際設(shè)備類型為智能穿戴設(shè)備等)上,考慮CPU、內(nèi)存、硬盤等硬件限制,往往會(huì)對(duì)系統(tǒng)進(jìn)行裁剪。如果在應(yīng)用后端功能開發(fā)時(shí)調(diào)用當(dāng)前系統(tǒng)沒有的能力,就可能會(huì)引發(fā)異常。
通常有兩種方式解決上述問題:
- 在應(yīng)用安裝包中描述其需要的系統(tǒng)能力,保證本應(yīng)用僅被分發(fā)和安裝到可以滿足其訴求的系統(tǒng)中。
- 在使用特定系統(tǒng)能力前,通過canIUse接口判斷系統(tǒng)能力是否存在,進(jìn)而執(zhí)行不同的邏輯。
審核編輯 黃宇
-
鴻蒙
+關(guān)注
關(guān)注
57文章
2410瀏覽量
43291 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3768瀏覽量
17020
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
?HarmonyOS"一次開發(fā),多端部署"優(yōu)秀實(shí)踐——玩機(jī)技巧

鴻蒙OS開發(fā):【一次開發(fā),多端部署】(一多天氣)項(xiàng)目

鴻蒙OS開發(fā):【一次開發(fā),多端部署】(音樂專輯主頁)

鴻蒙OS開發(fā):典型頁面場景【一次開發(fā),多端部署】實(shí)戰(zhàn)(音樂專輯頁2)

鴻蒙OS開發(fā):典型頁面場景【一次開發(fā),多端部署】實(shí)戰(zhàn)(設(shè)置典型頁面)

HarmonyOS\"一次開發(fā),多端部署\"優(yōu)秀實(shí)踐——玩機(jī)技巧,碼上起航
華為開發(fā)者大會(huì)2021:軟件部總裁龔體 鴻蒙系統(tǒng) 一次開發(fā) 多端部署 萬物互連

鴻蒙OS開發(fā):【一次開發(fā),多端部署】(簡介)

鴻蒙OS開發(fā):【一次開發(fā),多端部署】(多設(shè)備自適應(yīng)能力)簡單介紹

鴻蒙OS開發(fā):【一次開發(fā),多端部署】( 設(shè)置app頁面)

評(píng)論