常見問題
如何查詢設備類型
設備類型分為default(默認設備)、tablet、tv、wearable、2in1等,有多種查詢設備類型的方式。
- 通過命令行的方式查詢設備類型。 通過命令行查詢指定系統參數(const.product.devicetype)進而確定設備類型。
# 方法一 hdc shell param get "const.product.devicetype" # 方法二 hdc shell cat /etc/param/ohos.para | grep const.product.devicetype
- 在應用開發過程中查詢設備類型。
- 通過deviceInfo查詢設備類型。
import deviceInfo from'@ohos.deviceInfo' @Entry @Component struct GetDeviceTypeSample { @State deviceType:string='unknown' aboutToAppear() { this.deviceType= deviceInfo.deviceType } build() { Column() { Text(this.deviceType).fontSize(24) } .width('100%') .height('100%') } }
- 通過deviceInfo查詢設備類型。
如何在不同設備上為Ability配置不同的啟動模式
應用由一個或多個Ability組成,Ability支持單實例、多實例和指定實例3種[啟動模式],啟動模式可以在[配置文件(module.json5)]中通過launchType字段配置。啟動模式對應Ability被啟動時的行為,對啟動模式的詳細說明如下:
啟動模式 | 描述 | 說明 開發前請熟悉鴻蒙開發指導文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md ]點擊或者復制轉到。 |
---|---|---|
multiton | 多實例 | 每次startAbility都會啟動一個新的實例。 |
singleton | 單實例 | 系統中最多只可以存在一個實例,startAbility時,如果系統中已存在相應的Ability實例,則復用該實例。 |
specified | 指定實例 | 運行時由Ability內部業務決定是否創建多實例。 |
默認設備屏幕尺寸較小,采用multiton啟動模式不僅無法給用戶提供便利,反而可能消耗更多系統資源,故通常采用singleton啟動模式。平板屏幕尺寸較大且可能支持自由窗口,對于文檔編輯、網頁瀏覽等場景,使用multiton啟動模式可以提升用戶體驗。
本文中將默認設備和平板等歸為同一泛類,推薦同一泛類的設備共用HAP,同時本文也介紹了如何通過自適應布局能力和響應式布局能力開發出適配不同設備的頁面。這里將補充介紹,如何實現Ability在不同設備上以不同的模式啟動。
launchType字段配置為specified時,系統會根據AbilityStage的onAcceptWant的返回值確定是否創建新的實例。對于同一個應用,如果key已經存在,則復用該key對應的Ability,如果key不存在則新創建Ability。
可以將配置文件中的launchType字段配置為specified,同時在應用中加入如下代碼以實現目標效果。
- 非平板設備,直接將設備類型作為key,保證每次啟動的key相同,即以單實例模式運行。
- 平板設備,將設備類型與毫秒級時間戳疊加作為key,保證每次啟動的key不同,即以多實例模式運行。
// MyAbilityStage.ts
import AbilityStage from "@ohos.app.ability.AbilityStage"
import deviceInfo from'@ohos.deviceInfo'
import Want from '@ohos.app.ability.Want'
export default class MyAbilityStage extends AbilityStage {
...
private generateKey(): string {
// 如果是平板,則將設備類型和毫秒級時間戳疊加作為key,保證每次啟動的key都不同
if (deviceInfo.deviceType === 'tablet') {
return deviceInfo.deviceType + (new Date()).valueOf()
}
// 如果不是平板,直接以設備類型作為key,每次啟動的key相同
return deviceInfo.deviceType
}
onAcceptWant(want: Want) : string{
return this.generateKey()
}
}
如何開啟自由窗口
自由窗口功能默認是關閉的,可以通過如下方式開啟自由窗口功能。
# 取出窗口配置文件,并將文件中的< decor enable="false" >< /decor >修改為< decor enable="true" >< /decor >
hdc file recv system/etc/window/resources/window_manager_config.xml ./
# 以可讀寫的模式重新掛載根目錄,并更新配置文件
hdc shell mount -o rw,remount /
hdc file send window_manager_config.xml system/etc/window/resources/window_manager_config.xml
# 重啟設備,配置生效
hdc shell reboot
屏幕較小,通過手指操作窗口較為不便時,建議外接鼠標進行操作。
- 鼠標在應用頂部懸停,即可召喚出窗口工具欄。
- 點擊窗口工具欄中的縮放按鈕(從左到右第二個),即可讓應用以自由窗口的模式顯示。
- 在自由窗口模式下,可以通過拖動應用窗口的邊框或頂角,改變窗口尺寸同時觸發應用顯示刷新。 在調整窗口尺寸的過程中,窗口尺寸可能超出屏幕尺寸。此時應用顯示正常,但受限于屏幕尺寸,在屏幕中只能看到應用部分區域的顯示。可以通過移動窗口位置,查看應用其它區域的顯示。
如何限制自由窗口的尺寸調節范圍
自適應布局可以保證窗口尺寸在一定范圍內變化時,頁面的顯示是正常的。當窗口尺寸變化較大時,就需要額外借助響應式布局能力(如斷點等)調整頁面結構以保證顯示正常。通常每個斷點都需要開發者精心適配以獲得最佳的顯示效果,考慮到設計及開發成本等實際因素的限制,應用不可能適配從零到正無窮的所有窗口寬度。
不同設備或不同設備狀態,系統默認的自由窗口尺寸的調節范圍可能不同。開發者可以在[應用配置文件]中限制應用中各個Ability的自由窗口尺寸調節范圍,配置文件中影響自由窗口尺寸調節范圍的字段如下表所示。
配置文件字段 | 數據類型 | 描述 |
---|---|---|
minWindowWidth | 數值 | 標識該ability支持的最小的窗口寬度, 寬度單位為vp。 |
minWindowHeight | 數值 | 標識該ability支持的最小的窗口高度, 高度單位為vp。 |
maxWindowWidth | 數值 | 標識該ability支持的最大的窗口寬度,寬度單位為vp。 |
maxWindowHeight | 數值 | 標識該ability支持的最大的窗口高度, 高度單位為vp。 |
minWindowRatio | 數值 | 標識該ability支持的最小的寬高比。 |
maxWindowRatio | 數值 | 標識該ability支持的最大的寬高比。 |
如下所示,通過配置文件分別限制自由窗口的最大和最小尺寸。
{
"module": {
...
"abilities": [
{
...
"minWindowWidth": 320,
"minWindowHeight": 240,
"maxWindowWidth": 1440,
"maxWindowHeight": 900,
"minWindowRatio": 0.5,
"maxWindowRatio": 2,
}
]
}
}
如何獲取組件的尺寸
實際開發過程中,開發者可能有獲取頁面中某個組件或某塊區域的尺寸的訴求,以便通過手動計算等進行更精確的布局計算及優化。
開發者可以通過[組件區域變化事件](即組件顯示的尺寸、位置等發生變化時觸發的事件)來獲取指定組件的尺寸。
如下所示,通過onAreaChange事件獲取Row組件(頁面中白色區域)的尺寸。
@Entry
@Component
struct OnAreaChangeSample {
@State rate: number = 0.8
@State info: string = ''
// 底部滑塊,可以通過拖拽滑塊改變容器尺寸
@Builder slider() {
Slider({ value: this.rate * 100, min: 30, max: 80, style: SliderStyle.OutSet })
.blockColor(Color.White)
.width('60%')
.onChange((value: number) = > {
this.rate = value / 100;
})
.position({ x: '20%', y: '80%' })
}
build() {
Column() {
Column() {
Row() {
Text(this.info).fontSize(20).lineHeight(22)
}
.borderRadius(12)
.padding(24)
.backgroundColor('#FFFFFF')
.width(this.rate * 100 + '%')
.onAreaChange((oldValue: Area, newValue: Area) = > {
this.info = JSON.stringify(newValue)
})
}
this.slider()
}
.width('100%')
.height('100%')
.backgroundColor('#F1F3F5')
.justifyContent(FlexAlign.Center)
}
}
如何解決頂部單張大圖問題
解決方案
頂部背景圖被拉伸時,可以通過設置背景圖片的[backgroundImageSize]屬性,使得圖片大小能夠合理顯示,達到適配效果。
布局效果
參考代碼
@Entry
@Component
struct ImageClip {
build() {
// 設置背景圖片的backgroundImageSize屬性,使得圖片大小能夠合理顯示
Column()
.width('100%')
.height(300)
.backgroundColor('#ccc')
.backgroundImage($r('app.media.ImageOne'))
.backgroundImageSize(ImageSize.Cover)
.backgroundImagePosition(Alignment.Center)
}
}
如何解決Item內容過大
解決方案
在大屏上,Listitem內容會過大,頁面整體瀏覽內容減少。可通過以下兩種方法解決:
- 設置List列的最小寬度和最大寬度,使List組件根據寬度自適應決定列數。
- 借助柵格行組件[GridRow],調整不同的斷點下List組件的寬度。
布局效果
參考代碼
@Entry
@Component
struct ListLayout {
@State data: Resource[] = new Array(5).fill($r("app.media.image"))
@State breakPoint: string = 'sm'
build() {
GridRow() {
GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
List({ space: 24 }) {
ForEach(this.data, (item: Resource) = > {
ListItem() {
Image(item).margin({ left: 12, right: 12 })
}
})
}
// 設置列最小寬度和最大寬度
.lanes({ minLength: 300, maxLength: 360 }).padding(12)
}
}.onBreakpointChange((breakpoint: string) = > {
this.breakPoint = breakpoint
})
}
}
List() {
// ...
}
// 根據斷點設置List列數
.lanes(this.breakPoint === 'sm' ? 1 : 2)
如何解決Banner圖片過大
解決方案
在大屏上,Swiper圖片顯示內容過大,可以通過增加Swiper展示圖片數來調整圖片顯示大小。外層可以使用柵格組件[GridRow],通過調用OnBreakpointChange事件,調整不同的斷點下Swiper的前后邊距,實現在不同屏幕尺寸上的顯示不同Swiper圖片數。
布局效果
參考代碼
@Entry
@Component
struct SwiperLayout {
@State data: Resource[] = new Array(5).fill($r("app.media.sky"))
@State breakPoint: string = 'sm'
build() {
Row() {
GridRow() {
GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
Swiper() {
ForEach(this.data, (item: Resource) = > {
Image(item).width('100%').height(180)
})
}
.width('100%')
.itemSpace(24)
// 根據斷點設置Swiper前后邊距
.prevMargin(this.breakPoint === 'sm' ? 0 : 100)
.nextMargin(this.breakPoint === 'sm' ? 0 : 100)
}
}.onBreakpointChange((breakpoint: string) = > {
this.breakPoint = breakpoint
})
.height("60%")
.borderWidth(2)
}
}
}
如何解決信息流圖片過大
解決方案
針對信息流單張圖片過大的情況,設置[aspectRatio]和[constrainSize]屬性,可以通過對圖片的布局和尺寸進行約束,達到適配效果。
布局效果
參考代碼
@Entry
@Component
struct ImageConstrainSize {
@State breakPoint: string = 'sm'
build() {
GridRow(){
GridCol({ span: { sm: 12, md: 12, lg: 12 } }){
Column(){
Text('一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。')
// 設置aspectRatio和constrainSize屬性,可以對圖片的布局和尺寸進行約束
Image($r('app.media.ImageTwo'))
.width('30%')
.aspectRatio(0.5)
.constraintSize({ maxWidth: 240, minWidth: 180 })
Text('一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。')
}.alignItems(HorizontalAlign.Start)
}
}.onBreakpointChange((breakpoint: string) = > {
this.breakPoint = breakpoint
})
}
}
如何解決信息流_4宮格圖片過大
解決方案
在大屏上,Grid組件里的4宮格圖片大小過大,頁面瀏覽區域變少。可以借助柵格行組件[GridRow]來調整不同的斷點下Grid的寬度,解決大屏上Grid組件4宮格圖片過大的問題。
布局效果
參考代碼
@Entry
@Component
struct GridLayout {
@State data: Resource[] = new Array(4).fill($r("app.media.image"))
@State breakPoint: string = 'sm'
build() {
GridRow() {
GridCol({ span: { sm: 12, md: 12, lg: 12 } }) {
Column() {
Text('一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。')
Grid() {
ForEach(this.data, (item: Resource) = > {
GridItem() {
Image(item).width('100%').aspectRatio(1)
}
})
}.columnsTemplate('1fr 1fr')
.columnsGap(24)
.rowsGap(24)
// 根據斷點設置Grid寬度
.width(this.breakPoint === 'md' ? '60%' : '100%')
}.width('100%').alignItems(HorizontalAlign.Start)
}
}.onBreakpointChange((breakpoint: string) = > {
this.breakPoint = breakpoint
})
}
}
如何解決信息流_9宮格圖片過大
解決方案
在大屏上,Grid組件里的9宮格圖片大小過大,頁面整體瀏覽內容減少,可以設置Grid組件寬度和寬高比,使Grid組件保持固定大小,不會隨著屏幕尺寸變化而變化。
布局效果
參考代碼
`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
@Entry
@Component
struct GridWidth {
@State data: Resource[] = new Array(9).fill($r("app.media.sky"))
build() {
Column() {
Text('一次開發,多端部署,讓開發者可以基于一種設計,高效構建多端可運行的應用。')
Grid() {
ForEach(this.data, (item: Resource) = > {
GridItem() {
Image(item).width('100%').aspectRatio(1)
}
})
}
.columnsTemplate('1fr 1fr 1fr')
.columnsGap(12)
.rowsGap(12)
// 設置固定寬度和寬高比
.width(360)
.aspectRatio(1)
.padding(12)
}
.alignItems(HorizontalAlign.Start)
}
}
審核編輯 黃宇
-
鴻蒙
+關注
關注
57文章
2372瀏覽量
42914 -
鴻蒙OS
+關注
關注
0文章
189瀏覽量
4465
發布評論請先 登錄
相關推薦
評論