//
// Created with Android Studio.
// User: 三帆
// Date: 10/02/2019
// Time: 21:52
// email: [email protected]
// tartget: xxx
//
import 'dart:async';
import 'dart:core';
import 'package:city_pickers/modal/base_citys.dart';
import 'package:city_pickers/modal/point.dart';
import 'package:city_pickers/modal/result.dart';
import 'package:city_pickers/src/show_types.dart';
import 'package:city_pickers/src/util.dart';
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:permission_handler/permission_handler.dart';
class FullPage extends StatefulWidget {
final String? locationCode;
final ShowType showType;
final Map provincesData;
final Map citiesData;
FullPage({
this.locationCode,
required this.showType,
required this.provincesData,
required this.citiesData,
});
@override
_FullPageState createState() => _FullPageState();
}
// 界面状态
enum Status {
Province,
City,
Area,
Over,
}
class HistoryPageInfo {
Status status;
List itemList;
HistoryPageInfo({required this.status, required this.itemList});
}
class _FullPageState extends State {
/// list scroll control
late ScrollController scrollController;
/// provinces object [Point]
late List provinces;
/// cityTree modal ,for building tree that root is province
late CityTree cityTree;
/// page current statue, show p or a or c or over
late Status pageStatus;
/// show items maybe province city or area;
late List itemList;
/// body history, the max length is three
List _history = [];
/// the target province user selected
late Point targetProvince;
/// the target city user selected
Point? targetCity;
/// the target area user selected
Point? targetArea;
@override
void initState() {
super.initState();
scrollController = new ScrollController();
provinces = new Provinces(metaInfo: widget.provincesData).provinces;
cityTree = new CityTree(
metaInfo: widget.citiesData, provincesInfo: widget.provincesData);
itemList = provinces;
pageStatus = Status.Province;
try {
_initLocation(widget.locationCode);
} catch (e) {
print('Exception details:\n 初始化地理位置信息失败, 请检查省分城市数据 \n $e');
}
requestPermission();
///设置Android和iOS的apiKey
///key的申请请参考高德开放平台官网说明
///Android: https://lbs.amap.com/api/android-location-sdk/guide/create-project/get-key
///iOS: https://lbs.amap.com/api/ios-location-sdk/guide/create-project/get-key
// AMapFlutterLocation.setApiKey("f710757e921fdcdb74b7fc29695c589d", "f710757e921fdcdb74b7fc29695c589d");
///iOS 获取native精度类型
// if (Platform.isIOS) {
// requestAccuracyAuthorization();
// }
///注册定位结果监听
_locationListener = _locationPlugin.onLocationChanged().listen((Map result) {
setState(() {
_locationResult = result;
});
// _locationResult['province'] +
// _locationResult['city'] +
// _locationResult['district'] +
// _locationResult['street'];
print("定位结果${_locationResult['city']}");
});
}
Future back() {
HistoryPageInfo? last = _history.length > 0 ? _history.last : null;
if (last != null && mounted) {
this.setState(() {
pageStatus = last.status;
itemList = last.itemList;
});
_history.removeLast();
return Future.value(false);
}
return Future.value(true);
}
void _initLocation(String? locationCode) {
int _locationCode;
if (locationCode != null) {
try {
_locationCode = int.parse(locationCode);
} catch (e) {
print(ArgumentError(
"The Argument locationCode must be valid like: '100000' but get '$locationCode' "));
return;
}
targetProvince = cityTree.initTreeByCode(_locationCode);
if (targetProvince.isNull) {
targetProvince = cityTree.initTreeByCode(provinces.first.code!);
}
targetProvince.child.forEach((Point _city) {
if (_city.code == _locationCode) {
targetCity = _city;
targetArea = _getTargetChildFirst(_city) ?? null;
}
_city.child.forEach((Point _area) {
if (_area.code == _locationCode) {
targetCity = _city;
targetArea = _area;
}
});
});
} else {
targetProvince =
cityTree.initTreeByCode(int.parse(widget.provincesData.keys.first));
}
if (targetCity == null) {
targetCity = _getTargetChildFirst(targetProvince);
}
if (targetArea == null) {
targetArea = _getTargetChildFirst(targetCity!);
}
}
Result _buildResult() {
Result result = Result();
ShowType showType = widget.showType;
try {
if (showType.contain(ShowType.p)) {
result.provinceId = targetProvince.code.toString();
result.provinceName = targetProvince.name;
}
if (showType.contain(ShowType.c)) {
result.provinceId = targetProvince.code.toString();
result.provinceName = targetProvince.name;
result.cityId = targetCity?.code.toString();
result.cityName = targetCity?.name;
}
if (showType.contain(ShowType.a)) {
result.provinceId = targetProvince.code.toString();
result.provinceName = targetProvince.name;
result.cityId = targetCity?.code.toString();
result.cityName = targetCity?.name;
result.areaId = targetArea?.code.toString();
result.areaName = targetArea?.name;
}
} catch (e) {
print('Exception details:\n _buildResult error \n $e');
// 此处兼容, 部分城市下无地区信息的情况
}
// 台湾异常数据. 需要过滤
// if (result.provinceId == "710000") {
// result.cityId = null;
// result.cityName = null;
// result.areaId = null;
// result.areaName = null;
// }
return result;
}
Point? _getTargetChildFirst(Point target) {
if (target == null) {
return null;
}
if (target.child != null && target.child.isNotEmpty) {
return target.child.first;
}
return null;
}
popHome() {
Navigator.of(context).pop(_buildResult());
}
_onProvinceSelect(Point province) {
this.setState(() {
targetProvince = cityTree.initTree(province.code!);
});
}
_onAreaSelect(Point area) {
this.setState(() {
targetArea = area;
});
}
_onCitySelect(Point city) {
this.setState(() {
targetCity = city;
});
}
int _getSelectedId() {
int? selectId;
switch (pageStatus) {
case Status.Province:
selectId = targetProvince.code;
break;
case Status.City:
selectId = targetCity?.code;
break;
case Status.Area:
selectId = targetArea?.code;
break;
case Status.Over:
break;
}
return selectId ?? 0;
}
/// 所有选项的点击事件入口
/// @param targetPoint 被点击对象的point对象
_onItemSelect(Point targetPoint) {
_history.add(HistoryPageInfo(itemList: itemList, status: pageStatus));
print(this.isSelected.toString());
Status nextStatus = Status.Over;
List? nextItemList;
switch (pageStatus) {
case Status.Province:
_onProvinceSelect(targetPoint);
nextStatus = Status.City;
nextItemList = targetProvince.child;
if (!widget.showType.contain(ShowType.c)) {
nextStatus = Status.Over;
}
if (nextItemList.isEmpty) {
targetCity = null;
targetArea = null;
nextStatus = Status.Over;
}
break;
case Status.City:
_onCitySelect(targetPoint);
nextStatus = Status.Area;
nextItemList = targetCity?.child;
if (!widget.showType.contain(ShowType.a)) {
nextStatus = Status.Over;
}
if (nextItemList == null || nextItemList.isEmpty) {
targetArea = null;
nextStatus = Status.Over;
}
break;
case Status.Area:
nextStatus = Status.Over;
_onAreaSelect(targetPoint);
break;
case Status.Over:
break;
}
setTimeout(
milliseconds: 300,
callback: () {
if (nextItemList == null || nextStatus == Status.Over) {
return popHome();
}
if (mounted) {
this.setState(() {
itemList = nextItemList!;
pageStatus = nextStatus;
});
scrollController.jumpTo(0.0);
}
});
}
Widget _buildHead() {
String title = '请选择城市';
switch (pageStatus) {
case Status.Province:
this.isSelected = false;
break;
case Status.City:
title = targetProvince.name;
this.isSelected = true;
break;
case Status.Area:
title = targetCity!.name;
this.isSelected = true;
break;
case Status.Over:
break;
}
return Text(title);
}
List cityList = ["北京", "杭州", "宁波", "温州", "上海", "深圳"];
bool isSelected = false;
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: back,
child: Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: _buildHead(),
),
body: SafeArea(
bottom: true,
child:
// ListWidget(
// itemList: itemList,
// controller: scrollController,
// onSelect: _onItemSelect,
// selectedId: _getSelectedId(),
// ),
ListView(
children: [
Offstage(
offstage: isSelected,
child: Column(
children: [
Container(
height: 50, child:Text('${_locationResult==null?"重新定位":_locationResult['city']}')
// LocationNamePage()
// Text("重新定位"),
),
Container(
height: 100,
// decoration: new BoxDecoration(
// border: new Border.all(color: Colors.grey,
// width: 0.5),),
child: GridView.builder(
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3,
crossAxisSpacing: 10,
childAspectRatio:3,
mainAxisSpacing:10
),
physics: NeverScrollableScrollPhysics(),
shrinkWrap: true,
itemBuilder: (context, index) {
return Container(
alignment: Alignment.center,
decoration: new BoxDecoration(
border: new Border.all(
color: Colors.grey, width: 0.5),),
height: 8,
child: Text("${cityList[index]}"),
);
},
itemCount: 6,
),
),
],
)
),
Container(
child:
ListWidget(
itemList: itemList,
controller: scrollController,
onSelect: _onItemSelect,
selectedId: _getSelectedId(),
),
)
],
)
),
),
);
}
///定位
Map _locationResult= new Map();
AMapFlutterLocation _locationPlugin = new AMapFlutterLocation();
StreamSubscription