1. 沉浸式效果概述
典型應用全屏窗口UI元素包括狀態欄、應用界面和底部導航條,其中狀態欄和導航條,通常在沉浸式佈局下稱為避讓區;避讓區之外的區域稱為安全區。應用沉浸式效果主要指通過調整狀態欄、應用界面和導航條的顯示效果來減少狀態欄導航條等系統界面的突兀感,從而使用户獲得最佳的UI體驗。
默認情況下,UI元素被限制在安全區內(自動排除狀態欄和導航條)進行佈局,來避免界面元素被狀態欄和導航條遮蓋。
沉浸式效果根據不同的場景有多種解決方案,具體情況還是要根據場景來定。下面列舉幾種場景的場景,然後逐一講解各個場景下的沉浸式解決方案。
狀態欄和導航欄顏色相同時
狀態欄和導航欄顏色不同時
背景圖和視頻場景
滾動類場景
底部頁籤場景
圖文場景
2. 狀態欄和導航欄顏色相同時
沉浸式原理:將窗口背景顏色和安全區UI的背景顏色設置為相同顏色即可。
設置窗口背景色
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { window } from '@kit.ArkUI';
export default class EntryAbility extends UIAbility {
// ...
onWindowStageCreate(windowStage: window.WindowStage): void {
windowStage.loadContent('pages/Index', (err, data) => {
if (err.code) {
return;
}
// 設置全窗顏色和應用元素顏色一致
windowStage.getMainWindowSync().setWindowBackgroundColor('#008000');
});
}
}
設置安全區UI背景色
// xxx.ets
@Entry
@Component
struct Index {
build() {
Column() {
Row() {
Text('ROW1').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW2').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW3').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW4').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW5').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW6').fontSize(30)
}.backgroundColor(Color.Orange).padding(20)
}
.width('100%')
.height('100%')
.alignItems(HorizontalAlign.Center)
.justifyContent(FlexAlign.SpaceBetween)
.backgroundColor('#008000')
}
}
3. 狀態欄和導航欄顏色不同時
沉浸式原理:使用expandSafeArea屬性擴展安全區域。
安全區上面的元素樣式,擴展到狀態欄
安全區下面的元素樣式,擴展到導航欄
// xxx.ets
@Entry
@Component
struct Example {
build() {
Column() {
Row() {
Text('Top Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
}
.backgroundColor('#F08080')
// 設置頂部繪製延伸到狀態欄
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
Row() {
Text('ROW2').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW3').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW4').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('ROW5').fontSize(40)
}.backgroundColor(Color.Orange).padding(20)
Row() {
Text('Bottom Row').fontSize(40).textAlign(TextAlign.Center).width('100%')
}
.backgroundColor(Color.Orange)
// 設置底部繪製延伸到導航條
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
}
.width('100%').height('100%').alignItems(HorizontalAlign.Center)
.backgroundColor('#008000')
.justifyContent(FlexAlign.SpaceBetween)
}
}
4. 背景圖和視頻場景
沉浸式原理:使用expandSafeArea擴展安全區到狀態欄和滾動條
// xxx.ets
@Entry
@Component
struct SafeAreaExample1 {
build() {
Stack() {
Image($r('app.media.pc1010'))
.height('100%').width('100%')
// 圖片組件的繪製區域擴展至狀態欄和導航條。
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP, SafeAreaEdge.BOTTOM]
)
}.height('100%').width('100%')
}
}
5. 滾動場景
如下圖所示,觀察在滾動場景下設置沉浸式效果與沒有設置沉浸式效果的區別。
左圖:沒有設置沉浸式效果,滾動區域的頭部和底部被狀態欄和導航條遮蓋
右圖:有設置沉浸式效果,滾動區域的頭部和底部沒有被狀態欄和導航條遮蓋。
沉浸式原理:
1.設置窗口整體底色為灰色(#F2F2F2)
2.設置安全域背景與窗體底層相同,也是灰色(#F2F2F2)
3.List調用expandSafeArea屬性擴展視窗範圍擴展至導航條
// xxx.ets
@Entry
@Component
struct ListExample {
private arr: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
build() {
Column() {
List({space:15}) {
ForEach(this.arr, (item: number) => {
ListItem() {
Text(`${item}`)
.width('100%')
.height(100)
.borderRadius(10)
.backgroundColor(Color.White)
.textAlign(TextAlign.Center)
}
})
}
.width('90%')
.scrollBar(BarState.Off)
.divider({
strokeWidth:2,
startMargin:10,
endMargin:10,
color:Color.White
})
// List組件的視窗範圍擴展至導航條。
.expandSafeArea([SafeAreaType.SYSTEM],[SafeAreaEdge.TOP,SafeAreaEdge.BOTTOM])
}
.width('100%')
.height('100%')
.backgroundColor('#F2F2F2')
}
}
6. 圖文場景
如下圖所示,頁面結構分為上、下兩部分,上面是圖片,下面是文字;這種情況的沉浸式效果,分別對頂部圖標和底部文字進行延伸即可。
沉浸式原理:
頂部圖片往狀態欄延伸
底部文字區域往底部導航條延伸
@Entry
@Component
struct Index {
build() {
Column() {
Image($r('app.media.pc1010'))
.height('50%').width('100%')// 設置圖片延伸到狀態欄
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.TOP])
Column() {
Text('HarmonyOS 第一課')
.fontSize(32)
.margin(30)
Text('通過循序漸進的學習路徑,無經驗和有經驗的開發者都可以掌握ArkTS語言聲明式開發範式,體驗更簡潔、更友好的HarmonyOS應用開發旅程。')
.fontSize(20).margin(20)
}.height('50%').width('100%')
.backgroundColor('#F2F2F2')
// 設置文本內容區背景延伸到導航欄
.expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM])
}
.width('100%')
.height('100%')
}
}