應(yīng)用市場(chǎng)首頁(yè)
本小節(jié)將以應(yīng)用市場(chǎng)首頁(yè)為例,介紹如何使用自適應(yīng)布局能力和響應(yīng)式布局能力適配不同尺寸窗口。
頁(yè)面設(shè)計(jì)
一個(gè)典型的應(yīng)用市場(chǎng)首頁(yè)的UX設(shè)計(jì)如下所示。
觀察應(yīng)用市場(chǎng)首頁(yè)的頁(yè)面設(shè)計(jì),不同斷點(diǎn)下的頁(yè)面設(shè)計(jì)有較多相似的地方。
據(jù)此,我們可以將頁(yè)面分拆為多個(gè)組成部分。
- 底部/側(cè)邊導(dǎo)航欄
- 標(biāo)題欄與搜索欄
- 運(yùn)營(yíng)橫幅
- 快捷入口
- 精品應(yīng)用
- 開(kāi)發(fā)前請(qǐng)熟悉鴻蒙開(kāi)發(fā)指導(dǎo)文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md]點(diǎn)擊或者復(fù)制轉(zhuǎn)到。
接下來(lái)我們逐一分析各部分的實(shí)現(xiàn)。
底部/側(cè)邊導(dǎo)航欄
在sm和md斷點(diǎn)下,導(dǎo)航欄在底部;在lg斷點(diǎn)下,導(dǎo)航欄在左側(cè)。可以通過(guò)[Tab組件]的barPosition和vertical屬性控制TabBar的位置,同時(shí)還可以通過(guò)barWidth和barHeight屬性控制TabBar的尺寸。
import Home from '../common/Home';//組件請(qǐng)參考相關(guān)實(shí)例
import TabBarItem from '../common/TabBarItem';
@Entry
@Component
struct Index {
@State currentIndex: number = 0;
@StorageProp('currentBreakpoint') currentBreakpoint: string = 'md';
@Builder
tabItem(index: number, title: Resource, icon: Resource, iconSelected: Resource) {
TabBarItem({
index: index,
currentIndex: this.currentIndex,
title: title,
icon: icon,
iconSelected: iconSelected
})
}
build() {
// 設(shè)置TabBar在主軸方向起始或結(jié)尾位置
Tabs({ barPosition: this.currentBreakpoint === "lg" ? BarPosition.Start : BarPosition.End }) {
// 首頁(yè)
TabContent() {
Home()
}.tabBar(this.tabItem(0, $r('app.string.tabBar1'), $r('app.media.ic_home_normal'), $r('app.media.ic_home_actived')))
TabContent() {}.tabBar(this.tabItem(1, $r('app.string.tabBar2'), $r('app.media.ic_app_normal'), $r('app.media.ic_app_actived')))
TabContent() {}.tabBar(this.tabItem(2, $r('app.string.tabBar3'), $r('app.media.ic_game_normal'), $r('app.media.ic_mine_actived')))
TabContent() {}.tabBar(this.tabItem(3, $r('app.string.tabBar4'), $r('app.media.ic_search_normal'), $r('app.media.ic_search_actived')))
TabContent() {}.tabBar(this.tabItem(4, $r('app.string.tabBar4'), $r('app.media.ic_mine_normal'), $r('app.media.ic_mine_actived')))
}
.backgroundColor('#F1F3F5')
.barMode(BarMode.Fixed)
.barWidth(this.currentBreakpoint === "lg" ? 96 : '100%')
.barHeight(this.currentBreakpoint === "lg" ? '60%' : 56)
// 設(shè)置TabBar放置在水平或垂直方向
.vertical(this.currentBreakpoint === "lg")
}
}
另外在sm及l(fā)g斷點(diǎn)下,TabBar中各個(gè)Item的圖標(biāo)和文字是按照垂直方向排布的,在md斷點(diǎn)下,TabBar中各個(gè)Item的圖標(biāo)和文字是按照水平方向排布的。
@Component
export default struct TabBarItem {
@StorageProp('currentBreakpoint') currentBreakpoint: string = 'md';
build() {
if (this.currentBreakpoint !== 'md' ) {
// sm及l(fā)g斷點(diǎn)下,tabBarItem中的圖標(biāo)和文字垂直排布
Column() {
// ...
}.justifyContent(FlexAlign.Center).height('100%').width('100%')
} else {
// md斷點(diǎn)下,tabBarItem中的圖標(biāo)和文字水平排布
Row() {
// ...
}.justifyContent(FlexAlign.Center).height('100%').width('100%')
}
}
}
標(biāo)題欄與搜索欄
標(biāo)題欄和搜索欄,在sm和md斷點(diǎn)下分兩行顯示,在lg斷點(diǎn)下單行顯示,可以通過(guò)柵格實(shí)現(xiàn)。在sm和md斷點(diǎn)下,標(biāo)題欄和搜索欄占滿12列,此時(shí)會(huì)自動(dòng)換行顯示。在lg斷點(diǎn)下,標(biāo)題欄占8列而搜索欄占4列,此時(shí)標(biāo)題欄和搜索欄在同一行中顯示。
@Component
export default struct IndexHeader {
@Builder searchBar() {
Stack({alignContent: Alignment.End}) {
TextInput({ placeholder: $r('app.string.search') })
.placeholderColor('#FF000000')
.placeholderFont({ size: 16, weight: 400 })
.textAlign(TextAlign.Start)
.caretColor('#FF000000')
.width('100%')
.height(40)
.fontWeight(400)
.padding({ top: 9, bottom: 9 })
.fontSize(16)
.backgroundColor(Color.White)
Image($r('app.media.ic_public_search'))
.width(16)
.height(16)
.margin({ right: 20 })
}.height(56).width('100%')
}
@Builder titleBar() {
Text($r('app.string.tabBar1'))
.fontSize(24)
.fontWeight(500)
.fontColor('#18181A')
.textAlign(TextAlign.Start)
.height(56)
.width('100%')
}
build() {
// 借助柵格實(shí)現(xiàn)標(biāo)題欄和搜索欄在不同斷點(diǎn)下的不同布局效果。
GridRow() {
GridCol({ span: { xs: 12, lg: 8 } }) {
this.titleBar()
}
GridCol({ span: { xs: 12, lg: 4 } }) {
this.searchBar()
}
}
.width('100%')
}
}
運(yùn)營(yíng)橫幅
不同斷點(diǎn)下的運(yùn)營(yíng)橫幅,sm斷點(diǎn)下顯示一張圖片,md斷點(diǎn)下顯示兩張圖片,lg斷點(diǎn)下顯示三張圖片??梢酝ㄟ^(guò)[Swiper組件的displayCount屬性]實(shí)現(xiàn)目標(biāo)效果。
@Component
export default struct IndexSwiper {
@StorageProp('currentBreakpoint') currentBreakpoint: string = 'md';
@Builder swiperItem(imageSrc:Resource) {
Image(imageSrc)
.width('100%')
.aspectRatio(2.5)
.objectFit(ImageFit.Fill)
}
build() {
Swiper() {
this.swiperItem($r('app.media.ic_public_swiper1'))
this.swiperItem($r('app.media.ic_public_swiper2'))
this.swiperItem($r('app.media.ic_public_swiper3'))
// ...
}
.autoPlay(true)
.indicator(false)
.itemSpace(10)
// 配置不同斷點(diǎn)下運(yùn)行橫幅中展示的圖片數(shù)量
.displayCount(this.currentBreakpoint === 'sm' ? 1 : (this.currentBreakpoint === 'md' ? 2 : 3))
.width('100%')
.padding({ left: 12, right: 12, bottom: 16, top: 16 })
}
}
快捷入口
在不同的斷點(diǎn)下,快捷入口的5個(gè)圖標(biāo)始終均勻排布,這是典型的均分能力使用場(chǎng)景。
import { entranceIcons } from '../model/HomeData';
import { AllIcons } from '../model/HomeDataType';
@Component
export default struct IndexEntrance {
build() {
// 將justifyContent參數(shù)配置為FlexAlign.SpaceEvenly實(shí)現(xiàn)均分布局
Row() {
ForEach(entranceIcons, (icon: AllIcons) = > {
// 各快捷入口的圖標(biāo)及名稱
Column() {
// ...
}
})
}
.width('100%')
.height(64)
.justifyContent(FlexAlign.SpaceEvenly)
.padding({ left: 12, right: 12 })
}
}
精品應(yīng)用
隨著可用顯示區(qū)域的增加,精品應(yīng)用中顯示的圖標(biāo)數(shù)量也不斷增加,這是典型的延伸能力使用場(chǎng)景。精品游戲的實(shí)現(xiàn)與精品應(yīng)用類似,不再展開(kāi)分析。
import { AppItem, MyAppSource } from '../model/HomeDataType';
@Component
export default struct IndexApps {
private title?: Resource;
@StorageProp('currentBreakpoint') currentBreakpoint: string = 'md';
private apps: AppItem[] = [];
@Builder
appListHeader() {
Row() {
Text(this.title)
.width(100)
.fontSize(16)
.textAlign(TextAlign.Start)
.fontWeight(500)
Blank()
Text($r('app.string.more'))
.fontSize(14)
.textAlign(TextAlign.End)
.fontWeight(400)
.margin({ right: 2 })
Image($r('app.media.ic_public_arrow_right'))
.width(12)
.height(18)
.opacity(0.9)
.objectFit(ImageFit.Fill)
}
.margin({ bottom: 9, top: 9 })
.width('100%')
.alignItems(VerticalAlign.Bottom)
}
@Builder
appListItem(app:AppItem) {
Column() {
Image(app.image)
.width(this.currentBreakpoint === 'lg' ? 80 : 56)
.height(this.currentBreakpoint === 'lg' ? 80 : 56)
.margin({ bottom: 8 })
Text(app.title)
.width(this.currentBreakpoint === 'lg' ? 80 : 56)
.height(16)
.fontSize(12)
.textAlign(TextAlign.Center)
.fontColor('#18181A')
.margin({ bottom: 8 })
Text($r('app.string.install'))
.width(this.currentBreakpoint === 'lg' ? 80 : 56)
.height(28)
.fontColor('#0A59F7')
.textAlign(TextAlign.Center)
.borderRadius(this.currentBreakpoint === 'lg' ? 26 : 20)
.fontWeight(500)
.fontSize(12)
.padding({ top: 6, bottom: 6, left: 8, right: 8 })
.backgroundColor('rgba(0,0,0,0.05)')
}
}
build() {
Column() {
this.appListHeader()
// 借助List組件能力,實(shí)現(xiàn)延伸能力場(chǎng)景
List({ space: this.currentBreakpoint === 'lg' ? 44 : 20}) {
LazyForEach(new MyAppSource(this.apps), (app: AppItem)= > {
ListItem() {
// 每個(gè)應(yīng)用的圖標(biāo)、名稱及安裝按鈕
this.appListItem(app)
}
})
}
.width('100%')
.height(this.currentBreakpoint === 'lg' ? 140 : 120)
.listDirection(Axis.Horizontal)
}
.width('100%')
.height(this.currentBreakpoint === 'lg' ? 188 : 164)
.padding({ bottom: 8, left: 12, right: 12 })
}
}
運(yùn)行效果
將上述各頁(yè)面主要部分組合在一起后,即可完成整體頁(yè)面開(kāi)發(fā)。
import IndexSwiper from './IndexSwiper';
import IndexEntrance from './IndexEntrance';
import IndexApps from './IndexApps';
import { appList, gameList } from '../model/HomeData';
import IndexHeader from './IndexHeader';
@Component
struct IndexContent {
// ...
build() {
List() {
// 運(yùn)營(yíng)橫幅
ListItem() {
IndexSwiper()
}
// 快捷入口
ListItem() {
IndexEntrance()
}
// 精品應(yīng)用
ListItem() {
IndexApps({ title: $r('app.string.boutique_application'), apps: appList })
}
// 精品游戲
ListItem() {
IndexApps({ title: $r('app.string.boutique_game'), apps: gameList })
}
}
.width("100%")
}
}
@Entry
@Component
export default struct Home {
// ...
build() {
Flex({ direction: FlexDirection.Column, justifyContent: FlexAlign.Start, alignItems: ItemAlign.Start }) {
// 標(biāo)題欄和搜索欄
IndexHeader()
// 運(yùn)營(yíng)橫幅、快捷入口、精品應(yīng)用、精品游戲等
IndexContent()
}
.height('100%')
.backgroundColor("#F1F3F5")
}
}
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
本頁(yè)面的實(shí)際運(yùn)行效果如下圖所示。
-
移動(dòng)開(kāi)發(fā)
+關(guān)注
關(guān)注
0文章
52瀏覽量
9734 -
鴻蒙系統(tǒng)
+關(guān)注
關(guān)注
183文章
2634瀏覽量
66302 -
HarmonyOS
+關(guān)注
關(guān)注
79文章
1973瀏覽量
30143 -
OpenHarmony
+關(guān)注
關(guān)注
25文章
3713瀏覽量
16254 -
鴻蒙OS
+關(guān)注
關(guān)注
0文章
188瀏覽量
4382
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論