flutter

//
// 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> _locationListener = new StreamSubscription(); ///获取iOS native的accuracyAuthorization类型 void requestAccuracyAuthorization() async { AMapAccuracyAuthorization currentAccuracyAuthorization = await _locationPlugin.getSystemAccuracyAuthorization(); if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationFullAccuracy) { print("精确定位类型"); } else if (currentAccuracyAuthorization == AMapAccuracyAuthorization.AMapAccuracyAuthorizationReducedAccuracy) { print("模糊定位类型"); } else { print("未知定位类型"); } } /// 动态申请定位权限 void requestPermission() async { // 申请权限 bool hasLocationPermission = await requestLocationPermission(); if (hasLocationPermission) { print("定位权限申请通过"); } else { print("定位权限申请不通过"); } } /// 申请定位权限 /// 授予定位权限返回true, 否则返回false Future requestLocationPermission() async { //获取当前的权限 var status = await Permission.location.status; if (status == PermissionStatus.granted) { //已经授权 return true; } else { //未授权则发起一次申请 status = await Permission.location.request(); if (status == PermissionStatus.granted) { return true; } else { return false; } } } ///设置定位参数 void _setLocationOption() { AMapLocationOption locationOption = new AMapLocationOption(); ///是否单次定位 locationOption.onceLocation = false; ///是否需要返回逆地理信息 locationOption.needAddress = true; ///逆地理信息的语言类型 locationOption.geoLanguage = GeoLanguage.DEFAULT; locationOption.desiredLocationAccuracyAuthorizationMode = AMapLocationAccuracyAuthorizationMode.ReduceAccuracy; locationOption.fullAccuracyPurposeKey = "AMapLocationScene"; ///设置Android端连续定位的定位间隔 locationOption.locationInterval = 2000; ///设置Android端的定位模式
///可选值:
///
  • [AMapLocationMode.Battery_Saving]
  • ///
  • [AMapLocationMode.Device_Sensors]
  • ///
  • [AMapLocationMode.Hight_Accuracy]
  • locationOption.locationMode = AMapLocationMode.Hight_Accuracy; ///设置iOS端的定位最小更新距离
    locationOption.distanceFilter = -1; ///设置iOS端期望的定位精度 /// 可选值:
    ///
  • [DesiredAccuracy.Best] 最高精度
  • ///
  • [DesiredAccuracy.BestForNavigation] 适用于导航场景的高精度
  • ///
  • [DesiredAccuracy.NearestTenMeters] 10米
  • ///
  • [DesiredAccuracy.Kilometer] 1000米
  • ///
  • [DesiredAccuracy.ThreeKilometers] 3000米
  • locationOption.desiredAccuracy = DesiredAccuracy.Best; ///设置iOS端是否允许系统暂停定位 locationOption.pausesLocationUpdatesAutomatically = false; ///将定位参数设置给定位插件 _locationPlugin.setLocationOption(locationOption); } ///开始定位 void _startLocation() { ///开始定位之前设置定位参数 _setLocationOption(); _locationPlugin.startLocation(); // const timeout = const Duration(seconds: 5); // Timer(timeout, () { //callback function _stopLocation(); // 5s之后 // }); } ///停止定位 void _stopLocation() { _locationPlugin.stopLocation(); } /// /// // @override void dispose() { super.dispose(); ///移除定位监听 if (null != _locationListener) { _locationListener.cancel(); } ///销毁定位 _locationPlugin.destroy(); } } class ListWidget extends StatelessWidget { final List itemList; final ScrollController controller; final int selectedId; final ValueChanged onSelect; ListWidget({required this.itemList, required this.onSelect, required this.controller, required this.selectedId}); @override Widget build(BuildContext context) { ThemeData theme = Theme.of(context); return ListView.builder( controller: controller, physics: NeverScrollableScrollPhysics(), shrinkWrap: true, itemBuilder: (BuildContext context, int index) { Point item = itemList[index]; return Container( decoration: BoxDecoration( border: Border( bottom: BorderSide(color: theme.dividerColor, width: 1.0))), child: ListTileTheme( child: ListTile( title: Text(item.name), // item 标题 dense: true, // item 直观感受是整体大小 trailing: selectedId == item.code ? Icon(Icons.check, color: theme.primaryColor) : null, contentPadding: EdgeInsets.fromLTRB(24.0, .0, 24.0, 3.0), // item 内容内边距 enabled: true, onTap: () { onSelect(itemList[index]); }, // item onTap 点击事件 onLongPress: () {}, // item onLongPress 长按事件 selected: selectedId == item.code, // item 是否选中状态 ), ), ); }, itemCount: itemList.length, ); } }

    你可能感兴趣的:(flutter)