




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
以上為華為公司的商標(非詳盡清單未經華為公司書面事先明示萬物互聯時代應用開發面臨的挑戰與機遇鴻蒙應用多設備開發核心理念應用用戶體驗設計 面向多設備的應用體驗升級 3)智慧屏 多設備應用測試 應用上架與發布 2)多設備上架配置 3)上架審核 4)應用分發 術語2縱觀移動設備的發展歷程,早期的功能機時代,移動通信設備笨重且功能單一,只能用來,手機開始配備高分辨率屏幕,顯示效果也得到提升,支持簡單的互聯網接入,部分手機從信息獲取效率的角度出發,用戶始終期待擁有更大的屏幕,同時又想享受隨身攜帶的證明了能夠同時滿足大屏幕和便攜性的設計開始贏得用戶的青睞和市場。折疊機對消費者是福音,但是對開發者來說卻是一種挑戰,因為每個應用都要為各種折疊攝像頭翻轉、傳感器方向進行適配開發,極大增加了開發的工作量。如果不針對設備進行適3隨著創新硬件的不斷產生,折疊手機、平板電腦、個人電腦、智能座艙、智能電視的邊界開始變得越來越模糊,用戶越來越希望這些智能終端的體驗融合一致,提升設備之間的連終端產品形態多樣化,人均智能終端數量不斷增長,全場景的用戶l針對一款創新硬件設備,在適配開發帶來的高成本和不適配開發帶來的差用戶體驗l多設備、多操作系統下如何保持應用的用戶界面和交互一致體驗;l對于已維護多年的直板機應用,如何對體驗進行重新設計,為其他多元化屏幕比例未來的終端場景下,更加個性化的智能服務、更加沉浸的影音娛樂體驗、更高效的智慧辦公、更加以人為本的居家體驗,多個設備間的場景化體驗越來越重要,通過發揮不同形態設備的各自優勢,為用戶帶來全新的體驗躍升,這也是操作系統之上新用戶。新形態設備有助于催化應用體驗二次創新,實現業務的再次突破,獲得更大的商業5PC和穿戴設備的操作系統。由于操作系統間的差異,開發者不得不學習多套編程語言,并為不同設備的差異化體驗建立多個研發團隊。技術棧差異和團隊間的隔閡設備上的體驗出現割裂。應用內容無法跨設備復用,增加了開發者在多設備體驗一致性上的支持多種設備類型的操作系統。這一原生的統一操作系統為構建多設備統一生態環境奠定了一套技術實現多設備差異化體驗的應用開發。應用開發者在設計之初就為全場景設備做好體列多設備一致的開發者工具鏈,如工程管理、編譯構建、預覽調測、模擬器調測等,者可以完成適用于多種設備的應用開發,釋放開發者的技能學l統一交互邏輯:為了保障全場景跨設備體驗一致性,開發者只需要維護一套用戶界面代碼。通過統一的斷點系統,開盒即用的多態組件能力,開發者無需感知屏幕尺l統一工程和統一維護:開發者在同一個工程內處理應用功能代碼的編寫和管理,無需為每個設備維護獨立的代碼工程,無需構建多套編譯構建和發布的任務鏈,更簡l統一上架和分發:開發者通過統一流程構建的應用安裝包,只需將其上架到應用市場,應用市場自動針對目標設備進行安裝包的優化和分發處理,簡化了復雜的分發最佳體驗設計實踐,以及場景化的開發最佳實踐等,加速開發者掌握HarmonyOS應用開發技能。通過這些能力的支持,開發者能夠更快地積累經驗,輕松應對各種設備類型、不同7響應式設計:避免使用固定像素來作為界面布8除穿戴、IoT這些設備以外,移動端設備的尺寸形態也在逐步演進中。界面布局不應該是靜態且固定的,當顯示環境發生變化時,如橫豎屏切換、調節字體大小需要及時調整內容的布局方式進行適應變化。開發者可以通過調用斷點系統、柵格系統、響應式布局和媒體查詢等判斷邏輯,根據界面具體的展示內容進行更合理的變斷點是以應用窗口寬度為參照,將寬度和高度這兩個維度拆分成了幾個不同的區間(即圖斷點系統新增縱向區間為了讓應用在全場景設備上都能獲得一致自然的交互體驗,設計時需要為不同交互狀態下的各種輸入設備設計適合的交互方式。在傳統的開發模式中需要為不同的輸入設備進行適9穿戴、智慧屏等設備上。應用可能在多種設備上運行或在單一設備上被用戶通過多種輸入方式操控,這需要用戶界面能夠自動識別和支持不同的輸入設備,以便用戶以習慣的、舒適的驗一致性的同時,降低設計和開發的工作量。交互事應框架,通過將不同設備的交互行為轉化為同一個交互事件,保證控件在不同交互場景下的體驗一致性。開發者只需要調用所需的交互事件接口,無需為每個輸入設備單獨適配,從而簡化開發流程。該接口涵蓋用戶基礎的交互任務,并遵循了用戶在觸控、鼠以手勢交互為例,當應用運行在觸屏設備上時,用戶可以通過手指長開長按菜單;當應用運行在PC上時,用戶則可以通過單擊鼠標右鍵打開該菜單。典型的輸入方式包括但不限于觸屏上手指/手寫筆等直接交互、鼠標/觸摸板/鍵盤/表冠/遙控器/車定義。橫向與縱向斷點的判斷只是一種處理手段和方式,應用自身義一套展示規則,例如按照窗口尺寸拆分占比,調整。保證外屏的文本、圖標、布局信息結構均與內屏保持一致在組件能力上,ArkUI也提供了針對較小場要按照比例生效最大高度和高度等等。同時,也可以考慮在滑動界面的過程中對部分組件進行滑動隱藏操作,Tabs及Navigation組件均支持滑動隱藏屬性接口,可通過配置多設備場景的技術架構可在單設備應用架構的基礎上疊加,開發者需要重點關注多設備可復用和產品特有特性的代碼管理。為便于模塊管理和清晰查看模圖4-1多設備應用開發模型業務邏輯,具備高內聚、低耦合和可定制的特點。無需單獨部署的feature通常編feature通常編譯為Feature類型的HAP):并進行產品化的定制。各個product各自編譯為一個Entry類型的HAP間不可相互依賴。default類型的product是多個類型分界面在手機和平板上的UX設計相圖4-2多設備應用部署模型/application/application│卜--utils#工具類目錄:如網絡、圖片、文件管理工具等│卜--components#公共組件目錄:如共用的彈窗、列表、詳情頁組件等│L--...│卜--features#基礎特性目錄│卜--login#登錄模塊│卜--setting#設置模塊│L--...│L--product#產品定制目錄卜--phone#手機版本目錄卜--tablet#平板版本目錄卜--default#默認設備泛類目錄L--...布局能力涵蓋基礎的自適應布局和進階的響應式布局。使用自適應布局可以應對各種屏幕變化,但在大尺寸屏幕上,結合響應式布局能力,可以更有效地利用大尺寸屏幕優勢,為2.1.1自適應布局針對響應式設計方法,一多提煉了七種最常用的自適應布局場景能表4-1自適應布局能力2.1.2響應式布局合理使用自適應布局進行頁面開發后,無論窗口尺寸如何變化,界面布局都會自動適應窗口展示區域。然而,隨著窗口尺寸大幅增加后,原有的手機頁面內容在大現圖片異常放大、頁面內容稀疏以及留白過多等問題,影響用戶體驗。因此,開發者需要針對不同的窗口尺寸以及設備的使用場景,進行適當的增量設計和開發,以提供更貼近用戶場媒體查詢是多設備開發的另一個關鍵工具,支持查詢屏幕分辨率、橫豎屏、深淺色模式等與用戶界面相關的要素,允許開發者在這些場景變化時進行布局差異化場景下的界面精致體驗訴求。值得注意的是,當前媒體查詢還提供了設備類型的查詢能力,建議開發者盡量避免使用此功能進行頁面布局管理,以確保頁面布局在各種設備間最大化復柵格布局是用于處理多屏幕尺寸下動態布局的能力,適用于規律性的頁面核心思想是將頁面劃分為等寬的列數,便于對頁面元素進行定位和排版。柵格布局集成了斷點自定義能力,支持以窗口為參照物定義斷點區間,同時也支持以自身為參考進行組件級別的斷點自定義,使用場景更加靈活。關于柵格布局的更多信息,可以查閱柵格布局使用指南。2.2.1基礎組件ArkUI提供了多種維度和用途的基礎組件能力,用表4-2ArkUI基礎組件2.2.2多態組件備設計規范的高階精致多態組件,幫助開發者在多設備開發中實現一致性和個性化的平衡,智慧屏/座艙/API20以后支持:UIDesignKit官方文檔,組件庫持續構建中importimport{hdsSideBar,HdsNavigation,HdsTabs}from'@kit.UIDesignKit';ArkUI基礎導航組件的核心功能,還通過創新設計提升了用戶體驗,如分欄的斷點設計、開發者將了解如何在不同斷點下實現單欄、雙欄或三分欄的布局效果,以及如何在不同設備互體驗,如標題欄的自動顯隱功能、動態模糊等精致效果,以及HdsNavigation與開發者在不設置參數時遵從設計規范下的側邊欄規格。同時,HdsSidHdsSideBar({sideBarPanelBuilder:():void=>{this.sideBarBuilder()//側邊欄區contentPanelBuilder:():void=>{this.contentBuilder()//內容區sideBarContainerType:SideBarContainerType.Overlay//懸浮態設置側邊欄模糊效果設置:使用isSideBarBlur設HdsSideBarHdsSideBar({sideBarPanelBuilder:():void=>{this.sideBarBuilder()//側邊欄區contentPanelBuilder:():void=>{this.contentBuilder()//內容區isSideBarBlur:true//true為展示模糊透窗效果,false為不生效精致度、沉浸感、空間感等高階體驗。當應用開發者需要使用標后的標題欄樣式。當前支持通用模糊、過渡模糊、}style:{scrollEffectOpts:{enableScrollEffect:true,scrollEffectType:ScrollEffectType.COMMON_BLUR,blurEffectiveStartOffset:LengthMetrics.vp(0),blurEffectiveEndOffset:LengthMetrics.vp(20)originalStyle:{...},//系統狀態欄初始樣式。未設置systemBarStyle屬性時,顏色默認值同主標題欄字體顏色。scrollEffectStyle:{...}//HdsNavigation滾動動態樣式生效后,系統狀態欄對應的滾動后的樣式。未設置systemBarStyle屬性時,顏色默認值同主標題欄字體顏色。}標題欄動態顯隱。當應用開發者需要滾動內容區從而動態隱藏標題欄時,可以通過配置HdsNavigationHdsNavigation(){}.titleBar({.dynamicHideTitleBar({hideTitleArea:true,hideBottomBuilder:true,hideStatusBar:false,mode:HideMode.SCROLL_UP_TO,hideOffset:10組件還提供多種開箱即用的按鈕樣式,支持文字按鈕、頭像、圖標等多種操作體驗。同當應用開發者需要在標題欄區域增加自定義節點時,例如在標題欄上方區域增加分段按鈕,HdsNavigationHdsNavigation(){}.titleBar({content:{title:{mainTitle:'MainTitle',subTitle:'SubTitle'},stackBuilder:this.StackBuilder.bind(this),//標題欄頂部自定義區域bottomBuilder:{builder:this.BottomBuilder.bind(this),height:56,showType:BottomBuilderShowType.DIRECTLY_SHOW,}//標題欄底部自定義區域}三分欄效果。HdsSideBar提供了隱藏、懸浮、展開的側邊欄容器,HdsNavigation在HdsNavigation組件在對應屏幕斷點下默認呈現單欄形態。在闊折疊外屏時,建議使用當屏幕橫向大于840vp時,HdsSideBar通過設置iHdsSideBarHdsSideBar({sideBarPanelBuilder:():void=>{this.sideBarBuilder()//側邊欄區contentPanelBuilder:():void=>{HdsNavigation(){//導航組件}isShowSideBar:false;//當屏幕斷點≤840vp則設置為false;>840vp設置為true對于不同類型的智能設備,除了界面布局的差異化設計與開發,不同設備會為用戶提供多種交互方式,如通過觸摸屏、鼠標、觸控板等與設備互動。為了減少因不同交互方式單獨表4-3交互歸一的設備與事件懸浮(onHover)觸摸屏無懸浮操作光標移動到元素上光標移動到元素上筆尖靠近屏幕點擊(onClick)單指單擊單指輕點/單指按壓單擊鼠標左鍵筆尖點擊屏幕雙擊(TapGesture)雙擊輕點兩下/按壓兩下雙擊左鍵筆尖雙擊屏幕長按(LongPressGesture)單指長按單指長按長按左鍵筆尖長時間觸控屏幕上下文菜單(ContentMenu)單指長按雙指輕點/按壓單擊鼠標右鍵筆尖長時間觸控屏幕拖拽(Drag)長按并移動按壓并滑動按壓左鍵并移動鼠標筆尖長時間觸控屏幕后滑動輕掃(SwipeGesture)單指快速滑動雙指快速移動滾輪一格或快速滾動后停止筆尖在屏幕快速滑動滾動及平移(PanGesture)單指滑動雙指移動上下滾動滾輪或shift+上下滾動滾輪筆尖在屏幕滑動縮放(PinchGesture)雙指捏合或張開雙指捏合或張開手寫筆不支持此操作旋轉(RotationGesture)雙指互相以對方為中心旋雙指互相以對方為中心旋轉鼠標不支持此操作手寫筆不支持此操作按鍵事件,支持開發者進行場景化快捷鍵的定制開發,例如,使用空格鍵事件實現音視頻場2.4.1啟動頁都始終顯示啟動頁,有助于提升用戶在應用啟動階段的等待體驗。啟動頁的配置方式有簡易需要開發者針對不同屏幕大小綜合考慮并設計和配置相應的資源,往往無法應對變場景,我們建議開發者使用增強啟動頁方案進行應用啟動頁配置。增強方案可復雜的啟動頁配置。同時,相應資源也能夠具備根據窗口尺寸進行自動調整,更加適用于屏1.在創建的UIAbility模板中,上述startWindow字段未配置,開發者可以新增件需要由開發者自行創建并放置到工程目錄下。推薦的文件名及路徑為2.配置二級json文件的具體字段,包括背景顏色、插畫資源、品{{"startWindowIllustration":"$media:illustration",//啟動頁插畫資源"startWindowBrandingImage":"$media:branding",//啟動頁品牌標識"startWindowBackgroundColor":"$color:start_window_background",//啟動頁背景色"startWindowBackgroundImage":"$media:startingWindowBackground",//啟動頁背景圖片"startWindowBackgroundImageFit":"Cover"http://背景圖片在窗口內的填充方式}最終在各種屏幕尺寸的效果如下(自左向右分別對應:手機、手機應用分屏、大折疊展完成上述啟動頁配置后,即可支持在多種屏幕尺寸下自適應展示。對于進階場景,如深2.4.2橫豎屏旋轉HarmonyOS手機因其多樣化的形態和用戶使用場景,例如大折疊(X5、X6)擁有接近方型的屏幕,需要確保橫豎屏體驗一致;而三折疊(XT)在展開后接近平板,用戶也有橫屏的使用訴求。因此,強烈建議在應用啟動時或進入特定頁面時,避免強制設定屏幕方向橫豎屏控制行為在應用內是統一的,因此只需要對橫豎屏響應進行一次業務頁面內就不需要再重復處理橫豎屏響應。第一步,先依據窗口的虛擬像素尺寸并結合橫setDefaultOrientation():void{letwindowRect:window.Rect=this.windowObj!.getWindowProperties().windowRect;letwindowWidthVp:number=this.uiContext!.px2vp(windowRect.width);letwindowHeightVp:number=this.uiContext!.px2vp(windowRect.height);if(Math.min(windowWidthVp,windowHeightVp)>348){this.windowObj?.setPreferredOrientation(window.Orientation.AUTO_ROTATION_RESTRICTED);}else{this.windowObj?.setPreferredOrientation(window.Orientation.PORTRAIT);}}下一步,在窗口創建階段調用橫豎屏控制處理。由于三折開狀態時存在一次橫豎屏的狀態變化,因此還需要監聽窗口尺寸變化,并實時對橫豎屏響應onWindowStageCreate(windowStage:onWindowStageCreate(windowStage:window.WindowStage):void{//Mainwindowiscreated,setmainpageforthisabilitywindowStage.getMainWindow().then((windowObj)=>{this.windowObj=windowObj;windowStage.loadContent('pages/Index',(err)=>{this.uiContext=this.windowObj!.getUIContext();this.setDefaultOrientation();this.windowObj!.on('windowSizeChange',this.onWindowSizeChange);}下圖是在移動應用中經常可以看到的信息流頁面,開發者可通過對設計圖中的布局和體下面我們先基于頁面共性來搭建主體線框代碼架構,并按Flex({wrap:FlexWrap.Wrap}){MenuBar()SearchBar()}需要注意,在進行搜索框部分的代碼實現時,////XSmall和Small斷點時寬度為280vp,Medium、Large、XLarge時寬度為240vpTextInput({placeholder:'搜索...'}).width(newWidthBreakpointType(280,280,240,240,240).getValue(this.currentWidthBreakpoint))雖然也是基于斷點思路進行差異化實現,但以PuraX為例,其屏幕寬度是440vp,FlexFlex(){.layoutWeight(1)Button(){Image($r('app.media.search_history')).width('100%').height('100%').fillColor(Color.White))}}ArkUI的Tabs組件支持開箱即用的數據驅動式布局變化,開發者需要在滿足斷點是TabsTabs({barPosition:this.currentWidthBreakpoint===WidthBreakpoint.WIDTH_LG?BarPosition.Start:BarPosition.End}).vertical(this.currentWidthBreakpoint===WidthBreakpoint.WIDTH_LG)仍然在左側顯示,上面的代碼可以做以下優化以避免在TabsTabs({barPosition:[WidthBreakpoint.WIDTH_LG,WidthBreakpoint.WIDTH_XL].includes(this.currentWidthBreakpoint)?BarPosition.Start:BarPosition.End.vertical([WidthBreakpoint.WIDTH_LG,WidthBreakpoint.WIDTH_XL].includes(this.currentWidthBreakpoint))Banner圖區域是應用非常重要的區域,其使用場景是通過不要因為頭圖占用區域過大導致整體頁面布局不協調。針對這種場景,有兩種常用的設計和l輪播圖在不同屏幕尺寸下永遠展示一張圖片,用戶可左右滑動來切換。這種場景要privatebannerImgList:Array<BannerImg>=[newBannerImg($r('app.media.ic_banner_1'),$r('app.media.ic_banner_1_sm')),build(){Swiper(){LazyForEach(this.bannerDataSource,(item:BannerImg)=>{Row(){Image([WidthBreakpoint.WIDTH_XS,WidthBreakpoint.WIDTH_SM].includes(this.currentWidthBreakpoint)?item.getImgSrcSm():item.getImgSrc()).width('100%').height('100%').objectFit(ImageFit.Cover)}.width('100%').height('100%')},(item:BannerImg,index:number)=>index+JSON.stringify(item))}}上圖效果中使用了同一張圖片,可以看到,為了保證整備下使用相同圖片時會存在內容被裁切的現象。反之,若為了追求圖片完l輪播圖通過在不同屏幕上展示不同的圖片數量來更有效地利用寬屏的信息展示優勢。Swiper()Swiper(){LazyForEach(this.bannerDataSource,(item:BannerImg)=>{...},(item:BannerImg,index:number)=>index+JSON.stringify(item))}.displayCount([WidthBreakpoint.WIDTH_XS,WidthBreakpoint.WIDTH_SM].includes(this.currentWidthBreakpoint))?1:2)劃分為指定數量的等寬格子,列數僅與屏幕橫向寬度有關,因此,基于橫向斷點設置為Grid(){Grid(){LazyForEach(this.videoListItems,(item:VideoListItem,index:number)=>{GridItem(){...}},((item:VideoListItem,index:number)=>、${item.title}__${index}、))}.columnsTemplate(、repeate(${newBreakpointType(1,2,3,4,5).getValue(this.currentWidthBreakpoint)},1fr、)上述代碼中使用的Grid組件,適合宮格卡片高度相同的場景。對于高度不WaterFlow({WaterFlow({layoutMode:WaterFlowLayoutMode.SLIDING_WINDOW}){LazyForEach(this.videoListItems,(item:VideoListItem,index:number)=>{FlowItem(){...},((item:VideoListItem,index:number)=>、${item.title}__${index}、))}.columnsTemplate(newWidthBreakpointType(ColumnTemplateUnit.repeat(1),ColumnTemplateUnit.repeat(2),ColumnTemplateUnit.repeat(3),ColumnTemplateUnit.repeat(4),ColumnTemplateUnit.repeat(5)).getValue(this.currentWidthBreakpoint))ImageImage(item.preview).gesture(LongPressGesture({repeat:false}).onAction(()=>{)2.4.4分欄分欄場景較為常見的是社交類軟件的分欄和圖文類分欄,實際分欄聊天頁的分欄布局主體為聊天列表頁和聊天詳情頁兩個頁面,二者關通過點擊可跳轉至聊天詳情頁。在折疊屏展開態等屏幕尺寸較大的設備上,通常會采用兩個IM聊天的分欄布局是較為復雜的分欄布局場景,從直板機的單分欄到寬屏的三分欄,而且需要基于折疊機的開合、橫豎屏旋轉等外在窗口變化來進行響應式布局。從三個不同設這里建議使用Navigation組件實現路由導航。Navigation組件支持通過mode設置內時自動進入分欄模式。我們也可以基于實際業務場景結合斷點來精準控制單欄和分欄的觸發TabsTabs({TabContent(){HomeView()}.tabBar(this.tabBuilder(this.tabData[0],0))TabContent(){//聯系人列表ChatView()}.tabBar(this.tabBuilder(this.tabData[1],1))}NavigationNavigation(this.pageInfos){}[WidthBreakpoint.WIDTH_SM,WidthBreakpoint.WIDTH_XS].includes(this.currentWidthBreakpoint)?NavigationMode.Stack:NavigationMode.Split)Navigation(Navigation(this.pageInfos){TabsNavigation()}.navBarWidth([WidthBreakpoint.WIDTH_LG,WidthBreakpoint.WIDTH_XL].includes(this.currentWidthBreakpoint)?)在IM頁面的分欄場景中,初次進入時尚并在最右側的聊天區域顯示。這里涉及到的斷點區間包括Medium、Large和XLarge。Navigation(this.pageInfos)Navigation(this.pageInfos){}.onAnimationEnd((index:number,event:TabsAnimationEvent)=>{index===1&&[WidthBreakpoint.WIDTH_MD,WidthBreakpoint.WIDTH_LG,WidthBreakpoint.WIDTH_XL].includes(this.currentWidthBreakpoint)//進入聊天詳情占位頁面this.pageInfos.pushPath({name:'ConversationDetailNone'});}這里需要考慮一個體驗優化場景。當用戶在折疊屏展開態下正在與聯系人聊天時,如果因為一些原因必須將手機折疊使用時,頁面將保留聊天詳情頁面。但若此時用戶還沒有選擇化在折疊收起狀態到展開態也同樣需要。在該場景下,由于頁面路由狀態是聊天占位頁面,不能通過布局來改變什么。因此需要使用代碼邏輯來實現這個體驗優化,通過@Watch監聽斷點變化,并按需將頁面路由從占位頁面回退到聯系人列表頁面,或從聯系人列表頁面前進////監聽斷點變化@StorageLink('currentWidthBreakpoint')@Watch('currentWidthBreakpointChange')currentWidthBreakpoint:WidthBreakpoint=WidthBreakpoint.WIDTH_SM;//斷點變化的監聽回調處理currentWidthBreakpointChange(){if(this.currentSelectTabIndex!==1){return;}if(![WidthBreakpoint.WIDTH_XS,WidthBreakpoint.WIDTH_SM].includes(this.currentWidthBreakpoint)&&this.pageInfos.size()===0){//當斷點進入Medium、Large、XLarge時代表由折疊收起到展開態,我們路由到聊天詳情占位頁面this.pageInfos.pushPath({name:'ConversationDetailNone'});}elseif([WidthBreakpoint.WIDTH_XS,WidthBreakpoint.WIDTH_SM].includes(this.currentWidthBreakpoint)&&this.pageInfos.size()>0){//當斷點進入XSmall、Small時代表由展開態收起到折疊態,若路由棧頂部為占位頁ConversationDetailNone,則回退到聯系人列表頁面letpathNames:Array<string>=this.pageInfos.getAllPathName();if(pathNames.length>0&&pathNames[pathNames.length-1]==='ConversationDetailNone'){this.pageInfos.clear();return;}}}GridRowGridRow({columns:{xs:12,sm:12,md:10,lg:12,xl:12},gutter:20//圖片區域GridCol({span:{xs:12,//橫向斷點xs時占滿全部寬度sm:12,//橫向斷點sm時占滿全部寬度md:this.upDownStructure?10:6,//md斷點可切換上下布局或左右布局lg:6,//橫向斷點lg時占一半寬度xl:6//橫向斷點xl時占一半寬度}//圖片區功能}//文本區域GridCol({span:{xs:12,//橫向斷點xs時占滿全部寬度sm:12,//橫向斷點sm時占滿全部寬度md:this.upDownStructure?10:4,//md斷點可切換上下布局或左右布局lg:6,//橫向斷點lg時占一半寬度xl:6//橫向斷點xl時占一半寬度}//文本區功能}}實際應用開發過程中,開發者可能遇到不同尺寸的圖片,比如特別寬的圖片。為了保持圖片寬高比,在應用了左右分欄模式后圖片會很小;特別高的圖片在上下分欄模式時也會出以大折疊為例可以提供上下布局與左右分欄布局的動態切換功能。上述代碼中,加入了一個狀態變量upDownStructure控制兩個區域占用的柵格空間,用戶通過按鈕點擊來改變這個狀2.4.5視頻播放視頻場景在移動端用戶體驗中占據了非常大的部分,如長視頻看電影、直播、短視頻等長視頻界面在手機窄屏和雙折疊時自上向下排列信息塊,在這是典型的挪移布局場景,使用GridRow柵格組件將頁面劃分為兩部分:GridRowGridRow(){GridCol({span:{xs:12,sm:12,md:12,lg:9,xl:9}//視頻、相關列表、視頻簡介自上而下布局}GridCol({span:{xs:12,sm:12,md:12,lg:3,xl:3}//評論列表、評論功能自上而下布局}}這里使用GridRow的挪移布局進行實現,主要是要考慮到在折疊機開合場景時需要保障開合前后的觀影連續性。這里如果使用if-else的多分支編碼方式,就需要額外進行播放進市面上的視頻觀看場景主要是影視劇類的橫版視頻和短視頻類的豎版視頻,橫版視頻由于其比例的原因,通常可以通過橫屏全屏播放來將視頻畫面放大,提升觀看體驗。先來看下u類正方形屏幕,由于四邊比例接近,不需要處理旋轉角度,僅需要放大到充滿整個需要注意,我們這里是依據屏幕尺寸進行旋轉場景下有懸浮窗、應用分屏等非全屏場景,在手機場景下的全屏播importimport{display}from'@kit.ArkUI';letdisplayClass:display.Display|null=null;displayClass=display.getDefaultDisplaySync();this.screenHeight=display.getDefaultDisplaySync().height;//窗口高度this.screenWidth=display.getDefaultDisplaySync().width;//窗口寬度this.screenRatio=this.screenHeight/this.screenWidth;//窗口高寬比ifif(this.screenRatio>2){this.windowUtil.setMainWindowOrientation(window.Orientation.AUTO_ROTATION_LANDSCAPE);}在觀看橫版電視劇時,會有選集和換集的場景,這個時候為了不打斷觀影,可以使用側通過設計稿可以觀察到在方形屏時劇集內容由下方推出;矩形屏時劇集由右側推出,最終都會形成分欄效果。因此,可以使用前面章節提到的GridRow進行分欄實現,或者使用Flex彈性盒子的動態切換行列布局方向進行實現。前面章節已經多次提到使用GridRow和視頻與評論區實現:在手機窄屏時自上向下排列信息塊,在雙折疊態的寬屏時通過分欄布局,可以有效利用屏幕寬度的優勢來提升閱讀體驗交互體驗。這是典型的挪移布局場景,我們使用GridRow柵格組件將頁面劃分為兩部分:重介紹下豎版視頻的沉浸式體驗實現。我們以當下最熱門的短視頻界面,市面上的短視頻比例較為多樣化,開發者需要結合短視頻寬高比例和運行設備的屏幕尺寸再動態決定視頻的擺放位置。下面是我們以9:16寬高比的視頻源來進行實現,開發者可需要注意的是,與橫版視頻全屏完全不同的是,短視頻的頁面布局使用videoSizeChange來獲取視頻寬高,從而根據屏幕大小來調整視頻流比例大小。avPlayeravPlayer?.on('videoSizeChange',(width:number,height:number)=>{this.videoHeight=height;this.videoWeight=width度*視頻寬高比得到視頻流的高度,且此時視頻透過Tabs組件顯示,所以設置thisthis.barOverlap=false;this.xComponentController.setXComponentSurfaceRect({surfaceWidth:this.windowHeight*this.videoWeight/this.videoHeight,surfaceHeight:this.windowHeight視頻的寬度大于高度,此時視頻流的高度為窗口高度,視頻流寬度為視頻寬高比*窗口高度,且此時Tabs組件需要調整透明度,以達成沉浸式觀影體驗,所以設置thisthis.barOverlap=false;if(videoSizeHeight>=1){this.xComponentController.setXComponentSurfaceRect({surfaceWidth:videoSizeHeight*this.windowHeight,surfaceHeight:this.windowHeightthis.xComponentController.setXComponentSurfaceRect({surfaceWidth:this.windowWidth,surfaceHeight:this.windowWidth*this.videoHeight/this.videoWeight}thisthis.xComponentController.setXComponentSurfaceRect({surfaceWidth:videoSizeHeight*this.windowHeight,surfaceHeight:this.windowHeightthis.barOverlap=true且需要顯示上導航欄,視頻流的高度為窗口高度減去兩倍的上導航欄高度,視頻流thisthis.xComponentController.setXComponentSurfaceRect({surfaceWidth:videoSizeHeight*(this.windowHeight-2*this.statusHeight),surfaceHeight:(this.windowHeight-2*this.statusHeight)this.barOverlap=true;/openharmonysig/hadss_adaptive/blob/master/adaptive_video/README.md獲取。2.4.6相機預覽與拍照在拍照預覽或視頻錄制場景時需要對頁面布局進行布局自適應,避免畫面被拉伸或裁切。從相機預覽界面的設計圖可以看到,在三種設備上相機預覽區域尺寸是不一樣的,下面createPreviewOutput創建預覽輸出對象并綁定同XComponentXComponent({type:XComponentType.SURFACE,controller:this.mXComponentController.onLoad(async()=>{surfaceId=surfaceId=this.mXComponentController.getXComponentSurfaceId();previewOutput=cameraManager.createPreviewOutput(previewProfile,surfaceId);2.createPreviewOutput接口中的previewProfithisthis.windowClass.on('windowSizeChange',async(size)=>{this.mWindowWidth=size.width;this.mWindowHeight=size.height;//更新xcomponet寬高display.on("change",async()=>{this.initDisplayRotation=display.getDefaultDisplaySync().rotation//更新xcomponet寬高b.根據屏幕比例選擇合適的預覽分辨率,適用于全屏顯示的場景,如果業務需要特殊@@StatemConfigRatio:number=1;//設置分辨率比例初始值//根據屏幕初步計算比例,長邊/短邊this.mConfigRatio=(this.mWindowWidth>this.mWindowHeight)?(this.mWindowWidth/this.mWindowHeight):(this.mWindowHeight/this.mWindowWidth);this.cameraOutputCapabilitythis.cameraOutputCapability=this.cameraManager.getSupportedOutputCapability(cameraDevice,this.curSceneMode);letpreviewProfiles=cameraOutputCapability.previewProfiles;b)遍歷所有的預覽分辨率,選擇最接近mConfigRatio比例的預覽分辨率,可能存在支forfor(leti=0;i<previewProfiles.length;i++){if(previewProfiles[i].format!==this.previewProfileObj.format){continue;}letratio=previewProfiles[i].size.width/previewProfiles[i].size.height;//1088*1080//檢查寬高比是否匹配if(Math.abs(ratio-configRatio)>0.2)continue;//0.2的誤差可自行調整//選擇最接近的分辨率if(Math.abs(previewProfiles[i].size.height-this.reConfigType)<minDiff){optimalSize=previewProfiles[i];minDiff=Math.abs(previewProfiles[i].size.height-this.reConfigType);}}//...可以補充其他的選分辨率邏輯returnoptimalSize;this.mConfigRatiothis.mConfigRatio=optimalSize.size.width/optimalSize.size.height;letcameraArray:camera.CameraDevice[]=cameraManager.getSupportedCameras();if(cameraArray.length<=0){return[];}//選中需要的鏡頭,以后置為例cameraInput=cameraManager.createCameraInput(CameraPosition.CAMERA_POSITION_BACK,CameraType.CAMERA_TYPE_DEFAULT);提供的on('foldStatusChange')回調方法獲持的相機列表信息,再通過getSupportedCamer鏡頭,并根據訴求打開對應的攝像頭。參考適配不同折疊狀態的functionfunctioncallback(err:BusinessError,foldStatusInfo:camera.FoldStatusInfo):void{if(err!==undefined&&err.code!==0){return;}//折展態變化重新獲取鏡頭列表//更新屏幕比例}functionregisterFoldStatusChange(cameraManager:camera.CameraManager):void{cameraManager.on('foldStatusChange',callback);//注冊折疊狀態變化監聽}asyncupdateCameraInfo(){//最佳比例發生變化后,需要重新選擇鏡頭與分辨率,重新打開相機.if(surfaceId==''||this.mConfigRatio===0||//非首次進入(cameras.length===this.mLastCameraLength&&cameraPosition!==this.mLastCameraPosition)){//非切換鏡頭場景return;}//重新打開相機this.mLastCameraLength=cameras.length;this.mLastCameraPosition=cameraPosition;}并通過setPreviewRotation(pinitDisplayRotationinitDisplayRotation=display.getDefaultDisplaySync().rotationletletinitPreviewRotation=previewOutput.getPreviewRotation(initDisplayRotation*camera.ImageRotation.ROTATION_90);previewOutput.setPreviewRotation(initPreviewRotatpreviewOutput.setPreviewRotation(initPreviewRotation);thisthis.mRotate=display.getDefaultDisplaySync().rotation*camera.ImageRotation.ROTATION_90;@@StatemXComponentWidth:number=CameraConstants.X_COMPONENT_SURFACE_WIDTH;//定義為狀態監聽@StatemXComponentHeight:number=CameraConstants.X_COMPONENT_SURFACE_HEIGHT;updateXcomponentSize():void{letangleDiff=(this.mRotate+cameraDevice.cameraOrientation)%360;//用于判斷握持方向if(angleDiff===90||angleDiff===270){//豎向布局this.mXComponentWidth=this.mWindowWidth;this.mXComponentHeight=this.mConfigRatio*this.mWindowWidth;//1920*1080this.mXComponentWidth=this.mConfigRatio*this.mWindowHeight;this.mXComponentHeight=this.mWindowHeight;//1080*1920}}getRealDatagetRealData(data:sensor.GravityResponse):number{letgetDeviceDegree:number=0;letx=data.x;lety=data.y;letz=data.z;returngetDeviceDegree;letsd:Decimal=Decimal.atan2(y,-x);letsc:Decimal=Decimal.round(Number(sd)/3.141592653589*180)getDeviceDegree=90-Number(sc);getDeviceDegree=getDeviceDegree>=0?getDeviceDegree%360:getDeviceDegree%360+360;}returngetDeviceDegree;}functionfunctiongetPhotoRotation(photoOutput:camera.PhotoOutput,deviceDegree:number):camera.ImageRotation{letphotoRotation:camera.ImageRotation=camera.ImageRotation.ROTATION_0;try{photoRotation=photoOutput.getPhotoRotation(deviceDegree);//...打印異常}returnphotoRotation;}2.4.7窗口變化場景應對為了滿足用戶不同使用場景的需要,HarmonyOS提供了多種窗口形態,給用戶帶來更也給開發者帶來更多挑戰,開發者需要在單個設備上動l窗口尺寸非固定:用戶可通過折疊設備開合、分屏、懸浮窗、自由窗口等交互模式為了應對上述變化場景,推薦開發者使用響應式布局進行變化場景下自動調整布局,為用戶提供更加舒適的界面和更好的應用使用體驗。為了實現響應式布局開發,開發者需要關注的窗口核心狀態,通過響應核心狀態變化,可實現不同窗口通過監聽并響應核心狀態變化,刷新布局,即可實現基于斷點系統的作在不同窗口形態下,窗口尺寸可能會發生變化,下圖展示不同窗口形態下的窗口尺寸下圖展示窗口顯示大小縮放系數變化對窗口尺寸的影響,發生變化,因此在窗口px值沒有變化的情況下,窗口vp值會同步變化,從而導致斷點發生系統避讓區主要包括狀態欄、導航條、挖孔、軟鍵盤。對于折疊屏,在懸停態時,還需要開發者對折痕區域進行避讓。下圖展示不同類型的系當窗口寬度/高寬比跨越預設斷點閾值時,觸發布局重構事件。為了準確計算斷點,開發者需要監聽所有影響斷點計算的狀態,當前影響斷點計算的狀態包括窗口尺寸和窗口顯示importimport{window}from'@kit.ArkUI';exportdefaultclassEntryAbilityextendsUIAbility{onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.loadContent('pages/Index',(err)=>{//保存windowStage實例,用于獲取UIContext等操作AppStorage.setOrCreate("windowInstance",windowStage.getMainWindowSync())windowStage.getMainWindowSync().on('windowSizeChange',this.windowSizeChangeListener)windowStage.getMainWindowSync().on("systemDensityChange",this.systemDensityChangeListener)}windowSizeChangeListener(size:window.Size){}systemDensityChangeListener(density:number){}}當窗口尺寸變化或窗口顯示大小變化時,開發者可以在windowStage.loadContent()頁面加載后,通過UIContext中提供的getWindowWidthBreakpoint()和getWindowHeightBreakpoint()windowSizeChangeListener(size:windowSizeChangeListener(size:window.Size){EntryAbility.updateBreakpoint()}systemDensityChangeListener(density:number){EntryAbility.updateBreakpoint()}staticupdateBreakpoint(){letwindowInstance:window.Window=AppStorage.get("windowInstance")aswindow.WindowAppStorage.setOrCreate('windowWidthBreakpoint',windowInstance.getUIContext().getWindowWidthBreakpoint())AppStorage.setOrCreate('windowHeightBreakpoint',windowInstance.getUIContext().getWindowHeightBreakpoint())}import{window}from'@kit.ArkUI';exportdefaultclassEntryAbilityextendsUIAbility{onWindowStageCreate(windowStage:window.WindowStage):void{windowStage.getMainWindowSync().on("avoidAreaChange",this.avoidAreaChange)windowStage.getMainWindowSync().on("keyboardHeightChange",this.keyboardHeightChange)windowStage.loadContent('pages/Index',(err)=>{}avoidAreaChange(options:window.AvoidAreaOptions){}keyboardHeightChange(height:number){AppStorage.setOrCreate('keyboardHeight',height)}}窗口尺寸變化和避讓區變化之間沒有必然聯發生變化時,不會導致窗口尺寸變化,因此不會觸發windowSizeChange回調。所以對于安全區變化場景,開發者仍應當監聽avoidAreaChan優秀的應用用戶體驗包含合理且美觀的界面布局,和針對不同設備進行精心設計的場景化功能。為了方便開發者對多設備的差異性進行感知和功能實現,HarmonyOS開放能力定義了系統能力的最小單位:SystemCapability。不同的設備支持的SystemCapability集不同,開發者可以根據SystemCapability判斷當前系統是否支持該開HarmonyOS支持在手機、平板、PC、穿戴、座艙等不同品類設備上運行,這些設備在某個品類上不支持,而應用又未做好代碼保護,則應用運行在這個設備上如下表格所示,若沒有統一的策略處理不同設備品類間API的差異,應用使用了撥打是是否否是否是是否否是是否是是否是否否否否是否否否除此之外,由于設備能力的差異,同一個API在不同的設備品類上會出現行為不一致但在手機的智慧多窗模式下不支持此行為;在自由多窗下,允許應用最大化),為了解決以上兩類多設備兼容的問題,HarmonyOS在開發、編譯、上架等多個階段提3.API在不支持的設備品類上運行場景,應在文檔中明確告知會存在多設備兼容問題,獨立的特性。從應用的角度,SysCap決定了應用開發者可以使用的API范圍;從南向看,SysCap描述了一款HarmonyOS設備具備的能力。SysCap定義格式采用如下格式:每個SysCap對應多個API,這些API綁定在一起,隨著目標設備是否支持該API按SysCap分類是正交的,不會出現比如,藍牙的SysCap為SystemCapability.Commun……每個設備根據其硬件能力的不同,會隨著部件的定義,支持不同的SysCap,比如手機…………SDK提供全量的API給IDE,IDE通過開發者的項目支持的設備,篩選該設備支持要求能力集是應用的一個屬性,表示應用使用了全部的API涉及的SysCap集合,在對要求能力集修改要非常謹慎,因為其決定了該應用在應用市場上是否能在對應的設備syscap.json放在工程目錄appapp|--resources|--config.json|--syscap.jsonproduct是要求能力集,對于單設備應用開發,以該設備的支持能力集作為應用的要求能力集;對于跨設備開發,取各個設備支持能development是聯想能力集,對于單設備應用開發,以該設備的支持能力集作為應用的聯想能力集;對于跨設備開發,取各個設備支持能力集的并集作為若應用在syscap.json中的production中添加了不在支持能力集中的SysCap,則不能應用的聯想能力集API是多設備支持能力集的并集。應用要求的能力集是多設備支持應用使用要求能力集外的SysCap中的API,在調用前都需要使用canIUse函數進行CanIUse是HarmonyOSSDK提供的用于declaredeclarecanIUse(sysCap:string):boolean;CanIUse是全局可用的工具函數,不需要import即可使用。對于存在跨設備兼容性的API,在調用時,開發者需要先通過CanIUse來查詢當前設備是否支持此API,并對不支參考下面案例,地理位置功能并非在所有設備上均支持,開發者可基于Cimportimportgeolocationfrom'@ohos.geolocation';constisLocationAvailable:boolean=canIUse('SystemCapability.Location.Location');if(isLocationAvailable){geolocation.getCurrentLocation((location:Location)=>{//處理地理位置業務//對不支持地理位置獲取設備的補充處理}在創建應用/元服務工程時,Devicetypes字段可以選擇應用需要的設備類型,DevEco如果添加的是entry模塊,DevEcoStudio會檢測已有e{"module":{"name":"entry","type":"entry","description":"$string:module_desc","mainElement":"EntryAbility","deviceTypes":[//定義模塊支持的設備類型"phone","tablet",],}/application/application├——common#公共能力目錄│├——utils#工具類目錄:如網絡、圖片、文件管理工具等│├——components#公共組件目錄:如共用的彈窗、列表、詳情頁組件等│├——features#基礎特性目錄│└——products#產品定制目錄├——phone#手機版本目錄├——tablet#平板版本目錄├——default#默認設備泛類目錄當需要針對不同設備定制對應的資源文件時,可以通過資源目錄來管理。資源目錄名中可包含描述設備類型、屏幕密度、語言、文字、國家或地區、橫豎屏、顏色模式等限定詞,resources|base//默認的資源文件目錄|zh_CN-vertical-tablet-ldpi//自定義限定詞目錄。示例:中文-豎屏-平板-高分辨率
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 《機械設計基礎》課件-第3章 平面連桿機構
- 項鏈課件教學課件
- 農村電商培訓:助力鄉村振興與農業轉型
- 《旅行社經營管理》課件-第一章 概 述
- xx河流排水防澇設施建設項目風險管理方案(范文模板)
- 2025年新型全液壓鉆機項目合作計劃書
- 2025年自動酸雨采樣器及測定儀項目發展計劃
- 健康飲食產業園項目資金申請報告(范文模板)
- xx河流排水防澇設施建設項目招商引資報告
- 2025年解熱鎮痛類藥物項目發展計劃
- 年產xxx千件自行車配件項目可行性研究報告
- DZ/T 0261-2014滑坡崩塌泥石流災害調查規范(1∶50 000)
- T/CQAP 3014-2024研究者發起的抗腫瘤體細胞臨床研究細胞制劑制備和質量控制規范
- 初中體育教學中德育教育的現狀、問題與突破路徑探究
- 基層供銷社管理制度
- 農業供應鏈管理考試試題及答案
- 人行雨棚施工方案
- 2025-2030中國晶圓鍵合系統行業市場發展趨勢與前景展望戰略分析研究報告
- 從校園到職場:新員工角色轉換與職業化塑造
- 奶茶服務協議合同
- 學生食堂維修改造工程施工組織設計
評論
0/150
提交評論