一多天氣
介紹
本示例展示一個天氣應用界面,包括首頁、城市管理、添加城市、更新時間彈窗,體現一次開發,多端部署的能力。
1.本示例參考一次開發,多端部署的指導,主要使用響應式布局的柵格斷點系統實現在不同尺寸窗口界面上不同的顯示效果。
2.使用[SideBarContainer]實現側邊欄功能。
3.使用[柵格容器組件]實現界面內容的分割和展示。
4.使用Canvas和CanvasRenderingContext2D完成空氣質量和日出月落圖的曲線繪制。
開發前請熟悉鴻蒙開發指導文檔:gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
點擊或者復制轉到。
效果預覽
使用說明:
1.啟動應用后,首頁展示已添加城市的天氣信息,默認展示2個城市,左右滑動可以切換城市,在LG設備上,默認顯示側邊欄,側邊欄顯示時,右側內容區占2/3,側邊欄隱藏時,內容區自動鋪滿界面。
2.在支持窗口自由拖拽的設備上,拖拽窗口大小,可以分別實現拖動到最大窗口側邊欄顯示(點擊側邊欄控制按鈕可以隱藏和顯示側邊欄),拖動窗口縮小到MD大小時側邊欄和側邊欄控制按鈕隱藏。
3.在支持窗口自由拖拽的設備上,拖拽窗口大小,天氣內容區跟隨窗口大小會自動換行顯示。
4.點擊右上角菜單按鈕,在菜單中點擊更新時間,彈出更新時間彈窗,沒有功能,此處只做展示,在平板設備上顯示2列,在小屏設備上顯示一列。
5.點擊右上角菜單按鈕,在菜單中點擊管理城市,進入管理城市界面,展示已添加的城市,在平板設備上顯示2列,在小屏設備上顯示一列。
6.點擊管理城市界面的添加城市,進入添加城市界面,已添加的城市不可點擊,未添加的城市點擊可以添加并返回管理城市界面顯示。
工程目錄
/code/SuperFeature/MultiDeviceAppDev/Weather/product/default
└─src├─main│ ││ ├─ets│ │ ├─Application│ │ │ MyAbilityStage.ts //自定義ability│ │ ││ │ ├─common //公共資源庫│ │ ├─feature│ │ │ AirQualityFeature.ts //空氣繪畫│ │ │ SunCanvasFeature.ts //晴天繪畫│ │ ││ │ ├─MainAbility│ │ │ MainAbility.ts //主窗口│ │ ││ │ └─pages│ │ │ AddCity.ets //添加城市│ │ │ CityList.ets //城市列表│ │ │ Home.ets //入口│ │ ││ │ └─home│ │ AirQuality.ets //空氣質量│ │ HomeContent.ets //主頁面│ │ HoursWeather.ets //每小時天氣組件│ │ IndexEnd.ets //首頁尾 │ │ IndexHeader.ets //首頁頭│ │ IndexTitleBar.ets //首頁標題│ │ LifeIndex.ets //生活建議│ │ MultidayWeather.ets //天氣組件│ │ SideContent.ets //側邊欄│ │ SunCanvas.ets //晴天樣式│ │ UpdateTimeDialog.ets //時間更新彈窗│ ││ └─resources //資源包
具體實現
1、home.ets中引入SideContent()和homeContent()。
2、定義showSideBar來判斷是否展示側邊欄,定義mediaquery.MediaQueryListener媒體監聽器smListener、mdListener、lgListener。
3、在aboutToAppear調用mediaquery對界面進行監聽,[源碼參考]。
/** Copyright (c) 2022-2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import mediaquery from '@ohos.mediaquery';import HomeContent from './home/HomeContent';import IndexTitleBar from './home/IndexTitleBar';import SideContent from './home/SideContent';import { CityListData, Style, getBg, getCityListWeatherData, Logger } from '@ohos/common';const TAG: string = 'Home';@Entry@Componentstruct Home {@StorageLink('isRefresh') @Watch('refreshChange') isRefresh: boolean = false;@StorageLink('swiperIndex') swiperIndex: number = 0;@State curBp: string = 'md';@State cityListWeatherData: CityListData[] = getCityListWeatherData();@State popupState: boolean = false;@State showSideBar: boolean = false;private smListener: mediaquery.MediaQueryListener;private mdListener: mediaquery.MediaQueryListener;private lgListener: mediaquery.MediaQueryListener;build() {SideBarContainer(SideBarContainerType.Embed) {SideContent({ showSideBar: $showSideBar }).height('100%')Column() {IndexTitleBar({ showSideBar: $showSideBar }).height(56)Swiper() {ForEach(this.cityListWeatherData, (item, index) => {HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })}, item => item.city)}.id('swiper').padding({ left: Style.NORMAL_PADDING, right: Style.NORMAL_PADDING }).indicatorStyle({selectedColor: Color.White}).onChange(index => {this.swiperIndex = index;AppStorage.SetOrCreate('swiperIndex', this.swiperIndex);}).indicator(this.curBp !== 'lg').index(this.swiperIndex).loop(false).width('100%').layoutWeight(1)}.height('100%')}.height('100%').sideBarWidth('33.3%').minSideBarWidth('33.3%').maxSideBarWidth('33.3%').showControlButton(false).showSideBar(this.showSideBar).backgroundImageSize(ImageSize.Cover).backgroundImage(getBg(this.cityListWeatherData[this.swiperIndex].header.weatherType))}aboutToAppear() {this.smListener = mediaquery.matchMediaSync('(320vp<width<=600vp)');this.smListener.on("change", this.isBreakpointSM);this.mdListener = mediaquery.matchMediaSync('(600vp<width<=840vp)');this.mdListener.on("change", this.isBreakpointMD);this.lgListener = mediaquery.matchMediaSync('(840vp<width)');this.lgListener.on("change", this.isBreakpointLG);}aboutToDisappear() {this.smListener.off("change", this.isBreakpointSM);this.mdListener.off("change", this.isBreakpointMD);this.lgListener.off("change", this.isBreakpointLG);}isBreakpointSM = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'sm';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointMD = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'md';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointLG = (mediaQueryResult) => {if (mediaQueryResult.matches) {if (this.curBp !== 'lg') {this.showSideBar = true;}this.curBp = 'lg';AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}refreshChange() {Logger.info(TAG, `refreshChange}`);if (this.isRefresh) {this.cityListWeatherData = getCityListWeatherData();AppStorage.SetOrCreate('isRefresh', false);}Logger.info(TAG, `refreshChange, this.cityListWeatherData.length = ${this.cityListWeatherData.length}`);}}`HarmonyOS與OpenHarmony鴻蒙文檔籽料:mau123789是v直接拿`
4、監聽到當前屏幕大小,調用this.isBreakpoint斷點,對curBp、showSideBar進行賦值,[源碼參考]。
/** Copyright (c) 2022-2023 Huawei Device Co., Ltd.* Licensed under the Apache License, Version 2.0 (the "License");* you may not use this file except in compliance with the License.* You may obtain a copy of the License at** http://www.apache.org/licenses/LICENSE-2.0** Unless required by applicable law or agreed to in writing, software* distributed under the License is distributed on an "AS IS" BASIS,* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.* See the License for the specific language governing permissions and* limitations under the License.*/import mediaquery from '@ohos.mediaquery';import HomeContent from './home/HomeContent';import IndexTitleBar from './home/IndexTitleBar';import SideContent from './home/SideContent';import { CityListData, Style, getBg, getCityListWeatherData, Logger } from '@ohos/common';const TAG: string = 'Home';@Entry@Componentstruct Home {@StorageLink('isRefresh') @Watch('refreshChange') isRefresh: boolean = false;@StorageLink('swiperIndex') swiperIndex: number = 0;@State curBp: string = 'md';@State cityListWeatherData: CityListData[] = getCityListWeatherData();@State popupState: boolean = false;@State showSideBar: boolean = false;private smListener: mediaquery.MediaQueryListener;private mdListener: mediaquery.MediaQueryListener;private lgListener: mediaquery.MediaQueryListener;build() {SideBarContainer(SideBarContainerType.Embed) {SideContent({ showSideBar: $showSideBar }).height('100%')Column() {IndexTitleBar({ showSideBar: $showSideBar }).height(56)Swiper() {ForEach(this.cityListWeatherData, (item, index) => {HomeContent({ showSideBar: this.showSideBar, cityListData: item, index: index })}, item => item.city)}.id('swiper').padding({ left: Style.NORMAL_PADDING, right: Style.NORMAL_PADDING }).indicatorStyle({selectedColor: Color.White}).onChange(index => {this.swiperIndex = index;AppStorage.SetOrCreate('swiperIndex', this.swiperIndex);}).indicator(this.curBp !== 'lg').index(this.swiperIndex).loop(false).width('100%').layoutWeight(1)}.height('100%')}.height('100%').sideBarWidth('33.3%').minSideBarWidth('33.3%').maxSideBarWidth('33.3%').showControlButton(false).showSideBar(this.showSideBar).backgroundImageSize(ImageSize.Cover).backgroundImage(getBg(this.cityListWeatherData[this.swiperIndex].header.weatherType))}aboutToAppear() {this.smListener = mediaquery.matchMediaSync('(320vp<width<=600vp)');this.smListener.on("change", this.isBreakpointSM);this.mdListener = mediaquery.matchMediaSync('(600vp<width<=840vp)');this.mdListener.on("change", this.isBreakpointMD);this.lgListener = mediaquery.matchMediaSync('(840vp<width)');this.lgListener.on("change", this.isBreakpointLG);}aboutToDisappear() {this.smListener.off("change", this.isBreakpointSM);this.mdListener.off("change", this.isBreakpointMD);this.lgListener.off("change", this.isBreakpointLG);}isBreakpointSM = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'sm';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointMD = (mediaQueryResult) => {if (mediaQueryResult.matches) {this.curBp = 'md';this.showSideBar = false;AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}isBreakpointLG = (mediaQueryResult) => {if (mediaQueryResult.matches) {if (this.curBp !== 'lg') {this.showSideBar = true;}this.curBp = 'lg';AppStorage.SetOrCreate('curBp', this.curBp);}Logger.info(TAG, `this.curBp = ${this.curBp}`);}refreshChange() {Logger.info(TAG, `refreshChange}`);if (this.isRefresh) {this.cityListWeatherData = getCityListWeatherData();AppStorage.SetOrCreate('isRefresh', false);}Logger.info(TAG, `refreshChange, this.cityListWeatherData.length = ${this.cityListWeatherData.length}`);}}