import 'dart:convert'; import 'package:dio/dio.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:huixiang/utils/font_weight.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:pull_to_refresh/pull_to_refresh.dart'; import '../retrofit/data/ip_data.dart'; import '../retrofit/retrofit_api.dart'; class UnionSelectCity extends StatefulWidget { final Map arguments; UnionSelectCity({this.arguments}); @override State createState() { return _UnionSelectCity(); } } class _UnionSelectCity extends State { RefreshController refreshController = RefreshController(); Map areaMap; ApiService apiIpService; String ipName; int ipState = 0; List hotCity = []; List areaList = []; @override void initState() { super.initState(); areaCode(); queryIpInfo(); } void areaCode({String searchTxt}) async { var value = await rootBundle.loadString('assets/map_style/chinese_cities.json'); areaList.clear(); areaMap = jsonDecode(value); hotCity = (areaMap["热门城市"] as List).map((e) { return e["area"].toString(); }).toList(); areaMap.remove("热门城市"); Map tempAreaMap = jsonDecode(value); areaMap.forEach((key, value) { if (searchTxt != null && searchTxt.trim() != "") value.forEach((element) { if (!element["area"].contains(searchTxt)) (tempAreaMap[key] as List) .removeWhere((el) => el["area"] == element["area"]); }); if (tempAreaMap[key].isNotEmpty) areaList.add(key); }); areaMap = tempAreaMap; setState(() {}); } queryIpInfo() async { apiIpService = ApiService( Dio(), context: context, isIp: true ); IpData baseData = await apiIpService.getIpInfo().catchError((onError) {}); if (baseData?.city != null) { ipName = baseData.city.replaceAll("市", ""); if(ipName != widget.arguments["cityName"] ){ ipState=2; setState((){}); } } } @override Widget build(BuildContext context) { return Scaffold( resizeToAvoidBottomInset: false, backgroundColor: Color(0xFFF0F0F0), body: Container( color: Color(0xFFF0F0F0), child: Column( children: [ Container( color: Colors.white, padding: EdgeInsets.only(left: 14.w, top: 44.h, bottom: 24.h), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(); }, child: Container( padding: EdgeInsets.only(right: 21.w), child: Icon( Icons.arrow_back_ios, color: Colors.black, ), )), Expanded(child: searchCityItem()) ], ), Padding( padding: EdgeInsets.only(top: 16.h, bottom: 24.h), child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Padding( padding: EdgeInsets.only(right: 10.w), child: Text( (ipState == 0||ipState == 1) ? "当前位置" : "已选:", style: TextStyle( color: Color(0xFFA29E9E), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ), ), Image.asset( "assets/image/icon_union_location.webp", width: 20, height: 20, ), Expanded( // padding: EdgeInsets.only( // left: 8.w, // ), child: Text( (ipState== 1) ? (ipName??""):widget.arguments["cityName"] ?? "", style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ), ), if(ipState == 2) Icon( Icons.gps_fixed, color: Colors.grey, size: 18, ), if(ipState == 2) Padding(padding:EdgeInsets.only(left:5.w,right: 12.w), child:GestureDetector( behavior: HitTestBehavior.opaque, onTap: (){ setState((){ ipState = 1; Navigator.of(context).pop(ipName); }); }, child: Text( "重新定位", style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ), ),) ], )), Padding( padding: EdgeInsets.only(bottom: 16.h), child: Text( "热门城市", style: TextStyle( color: Color(0xFFA29E9E), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ), ), GridView.builder( itemCount: hotCity.length, padding: EdgeInsets.only(right: 14.h, bottom: 14.h), shrinkWrap: true, physics: NeverScrollableScrollPhysics(), gridDelegate: SliverGridDelegateWithFixedCrossAxisCount( crossAxisCount: 4, crossAxisSpacing: 12.w, mainAxisSpacing: 12.w, childAspectRatio: 2.5, ), itemBuilder: (context, index) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(hotCity[index]); setState((){}); }, child: Container( decoration: BoxDecoration( color: Color(0xFFF7F7F7), borderRadius: BorderRadius.circular(4), ), alignment: Alignment.center, child: Text( hotCity[index], style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ))); }, ), ], ), ), Expanded(child: sortList()) ], ), ), ); } Widget searchCityItem() { return Container( margin: EdgeInsets.fromLTRB(6.w, 0, 14.w, 0), padding: EdgeInsets.symmetric(vertical: 6.h), decoration: BoxDecoration( color: Color(0xFFF1F1F1), borderRadius: BorderRadius.circular(6), boxShadow: [ BoxShadow( color: Colors.black.withAlpha(12), offset: Offset(0, 3), blurRadius: 14, spreadRadius: 0, ), ], ), child: TextField( textInputAction: TextInputAction.search, onEditingComplete: () { FocusScope.of(context).requestFocus(FocusNode()); }, onChanged: (txt) { areaCode(searchTxt: txt); }, style: TextStyle( fontSize: 14.sp, ), decoration: InputDecoration( hintText: "搜索联盟会员店", hintStyle: TextStyle( fontSize: 12.sp, color: Color(0xFFB3B3B3), ), isCollapsed: true, prefixIcon:Padding(padding: EdgeInsets.only(left: 5.w,right: 5.w),child: Image.asset( "assets/image/icon_search.webp", width: 16.h, height: 16.h, ),), prefixIconConstraints: BoxConstraints(), border: InputBorder.none, ), ), ); } Widget sortList() { return areaList.length != 0 ?ListView.builder( padding: EdgeInsets.zero, itemCount: areaList.length, scrollDirection: Axis.vertical, shrinkWrap: true, physics: BouncingScrollPhysics(), itemBuilder: (context, position) { return GestureDetector( onTap: () {}, child: sortItem(position), ); }, ):Padding(padding:EdgeInsets.only(top:12.h), child: Text( "抱歉,未找到相关位置,可尝试修改后重试", style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 14.sp, ), )); } Widget sortItem(int position) { return Column( children: [ Container( width: double.infinity, // color: Colors.white, padding: EdgeInsets.only(top: 14.h, bottom: 4.h, left: 16.w), margin: EdgeInsets.only(bottom: 12.h), child: Text( areaList[position], style: TextStyle( color: Color(0xFF4D4D4D), fontWeight: MyFontWeight.medium, fontSize: 16.sp, ), ), ), Container( decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.w), color: Colors.white, ), margin: EdgeInsets.symmetric(horizontal: 14.w), padding: EdgeInsets.only( top: 8.h, ), child: mapWidget(position), ) ], ); } Widget mapWidget(position) { int mapIndex = 0; return Column( children: (areaMap[areaList[position]] as List).map((e) { mapIndex += 1; return globalRoamingItem( e, mapIndex == areaMap[areaList[position]].length); }).toList(), ); } Widget globalRoamingItem(data, isLast) { return GestureDetector( behavior: HitTestBehavior.opaque, onTap: () { Navigator.of(context).pop(data["area"]); }, child: Container( width: double.infinity, child: Text( data["area"], style: TextStyle( color: Color(0xFF000000), fontWeight: MyFontWeight.regular, fontSize: 14.sp, ), ), decoration: BoxDecoration( border: isLast ? null : Border( bottom: BorderSide( width: 1.w, color: Color(0xFFDCDCDC), style: BorderStyle.solid, ), ), ), padding: EdgeInsets.only(top: 16.h, bottom: 16.h, left: 16.w), ), ); } }