一多天氣
介紹
本示例展示一個天氣應用界面,包括首頁、城市管理、添加城市、更新時間彈窗,體現(xiàn)一次開發(fā),多端部署的能力。
1.本示例參考一次開發(fā),多端部署的指導,主要使用響應式布局的柵格斷點系統(tǒng)實現(xiàn)在不同尺寸窗口界面上不同的顯示效果。
2.使用[SideBarContainer]實現(xiàn)側(cè)邊欄功能。
3.使用[柵格容器組件]實現(xiàn)界面內(nèi)容的分割和展示。
4.使用Canvas和CanvasRenderingContext2D完成空氣質(zhì)量和日出月落圖的曲線繪制。
開發(fā)前請熟悉鴻蒙開發(fā)指導文檔 :[gitee.com/li-shizhen-skin/harmony-os/blob/master/README.md
]
效果預覽
使用說明:
1.啟動應用后,首頁展示已添加城市的天氣信息,默認展示2個城市,左右滑動可以切換城市,在LG設(shè)備上,默認顯示側(cè)邊欄,側(cè)邊欄顯示時,右側(cè)內(nèi)容區(qū)占2/3,側(cè)邊欄隱藏時,內(nèi)容區(qū)自動鋪滿界面。
2.在支持窗口自由拖拽的設(shè)備上,拖拽窗口大小,可以分別實現(xiàn)拖動到最大窗口側(cè)邊欄顯示(點擊側(cè)邊欄控制按鈕可以隱藏和顯示側(cè)邊欄),拖動窗口縮小到MD大小時側(cè)邊欄和側(cè)邊欄控制按鈕隱藏。
3.在支持窗口自由拖拽的設(shè)備上,拖拽窗口大小,天氣內(nèi)容區(qū)跟隨窗口大小會自動換行顯示。
4.點擊右上角菜單按鈕,在菜單中點擊 更新時間 ,彈出更新時間彈窗,沒有功能,此處只做展示,在平板設(shè)備上顯示2列,在小屏設(shè)備上顯示一列。
5.點擊右上角菜單按鈕,在菜單中點擊 管理城市 ,進入管理城市界面,展示已添加的城市,在平板設(shè)備上顯示2列,在小屏設(shè)備上顯示一列。
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 //空氣質(zhì)量
│ │ HomeContent.ets //主頁面
│ │ HoursWeather.ets //每小時天氣組件
│ │ IndexEnd.ets //首頁尾
│ │ IndexHeader.ets //首頁頭
│ │ IndexTitleBar.ets //首頁標題
│ │ LifeIndex.ets //生活建議
│ │ MultidayWeather.ets //天氣組件
│ │ SideContent.ets //側(cè)邊欄
│ │ SunCanvas.ets //晴天樣式
│ │ UpdateTimeDialog.ets //時間更新彈窗
│ │
│ └─resources //資源包
具體實現(xiàn)
1、home.ets中引入SideContent()和homeContent()。
2、定義showSideBar來判斷是否展示側(cè)邊欄,定義mediaquery.MediaQueryListener媒體監(jiān)聽器smListener、mdListener、lgListener。
3、在aboutToAppear調(diào)用mediaquery對界面進行監(jiān)聽,[源碼參考]。
/*
* 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
@Component
struct 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、監(jiān)聽到當前屏幕大小,調(diào)用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
@Component
struct 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}`);
}
}
審核編輯 黃宇
-
柵格
+關(guān)注
關(guān)注
0文章
13瀏覽量
11244 -
鴻蒙
+關(guān)注
關(guān)注
57文章
2352瀏覽量
42859 -
鴻蒙OS
+關(guān)注
關(guān)注
0文章
188瀏覽量
4396
發(fā)布評論請先 登錄
相關(guān)推薦
評論