1/* 2* Copyright (c) 2022-2023 Huawei Device Co., Ltd. 3* Licensed under the Apache License, Version 2.0 (the "License"); 4* you may not use this file except in compliance with the License. 5* You may obtain a copy of the License at 6* 7* http://www.apache.org/licenses/LICENSE-2.0 8* 9* Unless required by applicable law or agreed to in writing, software 10* distributed under the License is distributed on an "AS IS" BASIS, 11* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12* See the License for the specific language governing permissions and 13* limitations under the License. 14*/ 15 16import display from '@ohos.display' 17import Logger from '../util/Logger' 18import geolocation from '@ohos.geoLocationManager' 19import { listData, heatCity } from '../mock/LocationMock' 20import { MyDataSource } from '../util/DataSource' 21import httpRequestResponse from '../net/HttpRequestResponse' 22 23const TAG: string = '[Location]' 24 25@Entry 26@Component 27export struct Location { 28 @State alphabetIndex: number = 0 29 @State location: boolean = true 30 @State isCity: string = '' 31 @State currentLocation: string = '' 32 @State @Watch('positionChange') latitude: number = 0 33 @State @Watch('positionChange') longitude: number = 0 34 @State city: string = '' 35 @State isShow: boolean = true 36 private controller: TabsController = new TabsController() 37 private tabValue: string[] = ['A', 'B', 'C', 'F', 'G', 'H', 'J', 'L', 'N', 'Q', 'S', 'T', 'X', 'Y', 'Z'] 38 private scroller: Scroller = new Scroller() 39 private mockUrl = 'https://gitee.com/openharmony/applications_app_samples/raw/OpenHarmony_4.X_Dev/DataMock/LocationCity/mock.json' 40 41 async positionChange() { 42 Logger.info(TAG, `latitude = ${this.latitude}, longitude = ${this.longitude}`) 43 await this.requestResponse() 44 } 45 46 async aboutToDisappear() { 47 await geolocation.off('locationChange') 48 } 49 50 async requestResponse() { 51 Logger.info(TAG, `enter requestResponse`) 52 try { 53 let httpResponse = await httpRequestResponse.httpRequest(this.mockUrl, this.latitude, this.longitude) 54 Logger.info(TAG, `http response = ${JSON.stringify(httpResponse)}`) 55 let requestResponse = JSON.parse(httpResponse.result.toString()) 56 this.city = requestResponse.data 57 Logger.info(TAG, `this.city = ${JSON.stringify(this.city)}`) 58 } catch (error) { 59 Logger.info(TAG, `http request error: ${JSON.stringify(error)}`) 60 } 61 } 62 63 locationChange = async (location) => { 64 Logger.info(TAG, `locationChange location =${JSON.stringify(location)}`) 65 this.latitude = location.latitude 66 this.longitude = location.longitude 67 } 68 69 async getLocation() { 70 Logger.info(TAG, `enter getLocation`) 71 let requestInfo: geolocation.LocationRequest = { 72 priority: 0x203, // 快速获取位置优先,如果应用希望快速拿到1个位置,可以将优先级设置为该字段 73 scenario: 0x300, // 未设置场景信息 74 timeInterval: 0, // 上报位置信息的时间间隔 75 distanceInterval: 100, // 上报位置信息的距离间隔 76 maxAccuracy: 100 // 精度信息 77 } 78 Logger.info(TAG, `on locationChange before`) 79 geolocation.on('locationChange', requestInfo, this.locationChange) 80 Logger.info(TAG, `on locationChange end`) 81 } 82 83 build() { 84 Panel(this.isShow) { 85 Column() { 86 Column() { 87 Text($r('app.string.deliver_to')) 88 .fontSize(25) 89 .margin({ bottom: 30 }) 90 .alignSelf(ItemAlign.Start) 91 if (this.currentLocation) { 92 Text(`${this.currentLocation}` || $r('app.string.xian')) 93 .fontSize(20) 94 .alignSelf(ItemAlign.Start) 95 .id('currentLoc') 96 } else { 97 Text($r('app.string.current_positioning')) 98 .fontSize(20) 99 .opacity(0.6) 100 .alignSelf(ItemAlign.Start) 101 } 102 } 103 .width('100%') 104 .height(100) 105 .margin({ top: 20 }) 106 107 Row() { 108 Image($r("app.media.location")) 109 .width(22) 110 .height(22) 111 .aspectRatio(1) 112 .padding({ left: 4 }) 113 Text(this.city === '' ? $r('app.string.xian') : this.city) 114 .fontSize(20) 115 .fontColor('#E92F4F') 116 .margin({ left: 12 }) 117 .padding({ right: 3, top: 2 }) 118 } 119 .alignSelf(ItemAlign.Start) 120 .justifyContent(FlexAlign.Center) 121 .width(90) 122 .height(40) 123 .borderRadius(20) 124 .borderWidth(1) 125 .borderColor('#E92F4F') 126 .onClick(async () => { 127 Logger.info(TAG, `enter getLocation onClick`) 128 await this.getLocation() 129 }) 130 131 Column() { 132 Stack({ alignContent: Alignment.End }) { 133 Column() { 134 Row() { 135 Text($r('app.string.domestic_hot_city')) 136 .fontSize(20) 137 .fontColor('#000000') 138 .opacity(0.6) 139 } 140 .alignSelf(ItemAlign.Start) 141 .margin({ top: 10, bottom: 15 }) 142 143 Grid() { 144 LazyForEach(new MyDataSource(heatCity), (item, index) => { 145 GridItem() { 146 Text(`${item}`) 147 .margin({ bottom: 20 }) 148 .fontSize(20) 149 .maxLines(3) 150 .fontColor('#000000') 151 .onClick(() => { 152 this.currentLocation = item 153 }) 154 } 155 .id(`city${index + 1}`) 156 }) 157 } 158 .margin({ right: 60, top: 10 }) 159 .width('100%') 160 .height(130) 161 .columnsTemplate('1fr 1fr 1fr 1fr') 162 163 List({ space: 15, initialIndex: 0, scroller: this.scroller }) { 164 LazyForEach(new MyDataSource(listData), (firstItem) => { 165 ListItem() { 166 Column() { 167 Text(`${firstItem.name}`) 168 .height(30) 169 .fontSize(24) 170 .fontColor('#000000') 171 .width('100%') 172 .margin({ top: 10 }) 173 Divider() 174 .strokeWidth(0.8) 175 .color('#000000') 176 .opacity(0.2) 177 .margin({ right: 10, top: 12 }) 178 179 ForEach(firstItem.city, (item, index) => { 180 Text(`${item.name === undefined ? item : item.name}`) 181 .height(30) 182 .fontSize(20) 183 .width('100%') 184 .margin({ top: 16 }) 185 .onClick(() => { 186 this.currentLocation = item.name === undefined ? item : item.name 187 if (this.isCity === item.name) { 188 Logger.info(TAG, `item.name = ${item.name === undefined ? item : item.name}`) 189 this.isCity = '' 190 } else { 191 this.isCity = item.name === undefined ? item : item.name 192 } 193 }) 194 .id(`cityFirst${index + 1}`) 195 if (this.isCity === item.name) { 196 List() { 197 ForEach(item.city, (secondCity, index) => { 198 ListItem() { 199 Column() { 200 Text(`${secondCity}`) 201 .width('100%') 202 .height(30) 203 .fontSize(18) 204 .margin({ top: 4 }) 205 .id(`region${index + 1}`) 206 .onClick(() => { 207 this.currentLocation = `${item.name}/${secondCity}` 208 }) 209 } 210 } 211 }) 212 } 213 .height('9%') 214 .width('100%') 215 } 216 }) 217 } 218 } 219 }) 220 } 221 .height(580) 222 .width('100%') 223 .edgeEffect(EdgeEffect.None) 224 .listDirection(Axis.Vertical) 225 .onScrollIndex((firstIndex: number) => { 226 this.alphabetIndex = firstIndex 227 }) 228 } 229 230 Column() { 231 AlphabetIndexer({ arrayValue: this.tabValue, selected: this.alphabetIndex }) 232 .height('100%') 233 .font({ size: 16 }) 234 .popupColor('#FFFFFF') // 弹出框颜色 235 .selectedBackgroundColor(0xCCCCCC) // 选中背景颜色 236 .popupBackground(0xCCCCCC) // 弹出框背景颜色 237 .usingPopup(true) // 是否显示弹出框 238 .selectedFont({ size: 16, style: FontStyle.Normal }) // 选中的样式 239 .selectedColor('#969494') // 选中颜色 240 .popupFont({ size: 30, weight: FontWeight.Bolder }) // 弹出框的演示 241 .alignStyle(this.location ? IndexerAlign.Right : IndexerAlign.Left) 242 .onSelect((TabIndex: number) => { 243 this.scroller.scrollToIndex(TabIndex) 244 }) 245 } 246 .position({ x: '97%' }) 247 .margin({ top: 4 }) 248 } 249 } 250 } 251 .width('100%') 252 .padding({ left: '6.7%', right: '6.7%', top: 20 }) 253 .backgroundColor('#F1F3F5') 254 .borderRadius({ topLeft: 40, topRight: 40 }) 255 } 256 .dragBar(true) 257 .mode(PanelMode.Full) 258 } 259}