import 'dart:io'; import 'dart:math'; // import 'package:amap_location/amap_location.dart'; import 'package:amap_flutter_location/amap_flutter_location.dart'; import 'package:amap_flutter_location/amap_location_option.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:get_it/get_it.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:sport/pages/login/login_widget.dart'; import 'package:sport/pages/my/weight_page.dart'; import 'package:sport/pages/run/location.dart'; import 'package:sport/pages/run/run_page.dart'; import 'package:sport/pages/social/user_friend_add_page.dart'; import 'package:sport/provider/login_info_model.dart'; import 'package:sport/provider/user_model.dart'; import 'package:sport/router/navigator_util.dart'; import 'package:sport/services/api/inject_api.dart'; import 'package:sport/utils/toast.dart'; import 'package:sport/widgets/appbar.dart'; import 'package:sport/widgets/button_primary.dart'; import 'package:sport/widgets/decoration.dart'; import 'package:sport/widgets/dialog/alert_dialog.dart'; import 'package:sport/widgets/dialog/request_dialog.dart'; import 'package:sport/widgets/image.dart'; import 'package:sport/widgets/list_tile.dart'; import 'package:sport/widgets/space.dart'; class UserInfoPage extends StatefulWidget { @override State createState() => _PageState(); } class _PageState extends State with InjectLoginApi,InjectApi { late LoginInfoModel _loginInfoModel; int _genderController = 1; // 默认选中男 String? _name; // 用户名 File? _lastCropped; late ValueNotifier num; @override void initState() { super.initState(); _loginInfoModel = GetIt.I(); initNameCardCount(); } initNameCardCount() async{ int? _num = (await api.getCountNameCard()).data; num = new ValueNotifier(_num ?? 0); } @override void dispose() { super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, body: NestedScrollView( headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { return [buildSliverAppBar(context, "用户信息")]; }, body: ListView( padding: EdgeInsets.symmetric(horizontal: 12.0, vertical: 12.0), physics: NeverScrollableScrollPhysics(), shrinkWrap: true, children: divideTiles( context: context, includeLast: true, tiles: [ ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "头像", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { // 没有头像就为空... return model.user.avatar != null ? Container( width: 40.0, height: 40.0, child: CircleAvatar( backgroundColor: Colors.black26, radius: 100, backgroundImage: userAvatarProvider(model.user.avatar), ), ) : Container(); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async { selectImage(context); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "用户名称", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { return Text(model.user.name, style: Theme.of(context).textTheme.bodyText2!); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async { SharedPreferences prefs = await SharedPreferences.getInstance(); String name = prefs.getString("name") ??""; _showDialog((TextEditingValue name) async { await request(context, () async { await _loginInfoModel.updateUserInfo(context, name.text, Provider.of(context, listen: false).user.gender ?? 0); }); Navigator.maybePop(context); },name:name); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "性别", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { return Text(model.user.gender == 1 ? "男" : "女", style: Theme.of(context).textTheme.bodyText2!); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async{ var user = Provider.of(context, listen: false).user; await _showGenderDialog(user.gender ?? 0, (int _gender) async { await request(context, () async { await _loginInfoModel.updateUserInfo(context, Provider.of(context, listen: false).user.name, _gender); }); }); await _showMetDialog("修改性别后将影响下次运动的卡路里、运动强度的计算"); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "年龄", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { return Text(model.user.age != null ? "${model.user.age}岁" : "请选择你的年龄", style: Theme.of(context).textTheme.bodyText2!); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () { var user = Provider.of(context, listen: false).user; _showAgeDialog(user.age ?? 1, (int age) async { await request(context, () async { await _loginInfoModel.updateUserInfo( context, Provider.of(context, listen: false).user.name, Provider.of(context, listen: false).user.gender ?? 0, age: age); }); Navigator.maybePop(context); }); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "体重", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { return Text(model.user.weight != 0 ? "${model.user.weight}kg" : "请选择你的体重", style: Theme.of(context).textTheme.bodyText2!); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async { await NavigatorUtil.goPage(context, (context) => WeightPage(update: true,)); await _showMetDialog("修改体重后将影响下次运动的卡路里、运动强度的计算"); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "城市", style: TextStyle(fontSize: 16.0), ), Consumer( builder: (_, model, __) { String? province = model.user.province; String? city = model.user.city; String? district = model.user.district; String? _address = ""; // print(_address); if (province != null && city != null && district != null) { _address = "$province-$city"; } return Text(_address != "" ? "$_address" : "请选择你的城市", style: Theme.of(context).textTheme.bodyText2!); }, ) ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async { Map result = await [Permission.locationWhenInUse].request(); if (!result.values.any((element) => element.isGranted)) { ToastUtil.show("请授权后使用该功能!"); return; } if (await showDialog( context: context, builder: (context) => CustomAlertDialog(title: '是否重新定位?', ok: () => Navigator.of(context).pop(true)), ) == true) { await request(context, () async { try { Location? location = await _location(); if (location != null) { await _loginInfoModel.updateUserInfo( context, Provider.of(context, listen: false).user.name, Provider.of(context, listen: false).user.gender??0, districtId: int.parse(location.adcode!)); } } catch (e, s) { print(e); debugPrintStack(stackTrace: s); } }); } // // var user = Provider.of(context, listen: false).user; // CityResult initCity = CityResult(); // initCity.province = user.province; // initCity.city = user.city; // initCity.county = user.district; // CityResult result = await showCityPicker(context,initCity: initCity); // // if(result == null) // return; // // print(result.county); // print(result.city); // print(result.province); // // print(result.cityCode); // print(result.countyCode); // print(result.provinceCode); // // await _loginInfoModel.updateUserInfo( // context, Provider.of(context, listen: false).user.name, Provider.of(context, listen: false).user.gender, // cityId: int.parse(result.cityCode), districtId: int.parse(result.countyCode), provinceId: int.parse(result.provinceCode)); }, ), ListTile( title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "二维码名片", style: TextStyle(fontSize: 16.0), ), Container( width: 22.0, height: 22.0, child: Image.asset("lib/assets/img/mine_icon_code.png"), ), ], ), contentPadding: EdgeInsets.symmetric(horizontal: 0.0), trailing: arrowRight5(), onTap: () async { NavigatorUtil.goPage(context, (context) => UserFriendAddPage()); }, ), ], ).toList(), ), )); ; } _showDialog(Function callBack,{String? name}) { TextEditingController _controller = new TextEditingController(); _controller.text = name ??""; return showDialog( context: context, barrierDismissible: true, builder: (context) { return AlertDialog( contentPadding: EdgeInsets.all(6.0), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), content: Container( width: 300, height: 200, child: Column( children: [ // Divider(), Space( height: 30.0, ), Padding( padding: const EdgeInsets.all(16.0), child: TextField( textAlign: TextAlign.center, controller: _controller, autofocus: true, maxLength: 7, decoration: InputDecoration( counterText: '', // helperText: '用户名长度为2-10个字母,数字,中文', // hintText: name, helperMaxLines: 1, focusedBorder: UnderlineInputBorder( borderSide: BorderSide(color: Color(0xffF1F1F1)), ))), ), Padding( padding: EdgeInsets.fromLTRB(20.0, 20.0, 20.0, 0), child: Row( children: [ Expanded( child: MainButton( type: "cancel", content: "取消", callback: () => {Navigator.of(context).pop()}, height: 35.0, textColor: Color(0xff333333), ), ), Space( width: 12.0, ), Expanded( child: ValueListenableBuilder( valueListenable: num, builder: (context, index, child) { return MainButton( type: "confirm", content: "改名卡($index)", callback: () { if (index > 0) { callBack(_controller.value); }else{ ToastUtil.show("您没有改名卡喔~!"); } }, height: 35.0, buttonColor: index <= 0 ? Color(0xffFFC400).withOpacity(0.3) : Color(0xffFFC400), ); }, ), ), ], ), ), ], ), ), ); }); } _showGenderDialog(int gender, Function callback) { var array = ["男", "女"]; int _index = gender == 2 ? 1 : 0; return showDialog( context: context, barrierDismissible: true, builder: (context) { return AlertDialog( contentPadding: EdgeInsets.all(6.0), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), content: Container( width: 300, height: 200, child: Column( children: [ Row( children: [ IconButton( onPressed: () { Navigator.of(context).pop(); }, icon: Text("取消")), Expanded( child: Center( child: Text( "修改性别", style: Theme.of(context).textTheme.headline3, ))), IconButton( onPressed: () async { await callback(_index); Navigator.of(context).pop(); }, icon: Text( "确认", style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Theme.of(context).accentColor), )), ], ), Divider(), Expanded( child: Padding( padding: const EdgeInsets.all(16.0), child: CupertinoPicker.builder( scrollController: FixedExtentScrollController(initialItem: _index), itemExtent: 40, backgroundColor: Colors.white, onSelectedItemChanged: (index) { // print(index); _index = index + 1; }, itemBuilder: (context, index) { return Text("${array[index]}"); }, childCount: array.length, )), ), ], ), ), ); }); } _showAgeDialog(int age, Function callback) { List _ages = List.generate(100, (index) => index); int _index = min(100, age); return showDialog( context: context, barrierDismissible: true, builder: (context) { return AlertDialog( contentPadding: EdgeInsets.all(6.0), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10)), content: Container( width: 300, height: 200, child: Column( children: [ Row( children: [ IconButton( onPressed: () { Navigator.of(context).pop(); }, icon: Text("取消")), Expanded( child: Center( child: Text( "修改年龄", style: Theme.of(context).textTheme.headline3, ))), IconButton( onPressed: () { callback(_index); Navigator.of(context).pop(); }, icon: Text( "确认", style: Theme.of(context).textTheme.subtitle1!.copyWith(color: Theme.of(context).accentColor), )), ], ), Divider(), Expanded( child: Padding( padding: const EdgeInsets.all(16.0), child: CupertinoPicker.builder( scrollController: FixedExtentScrollController(initialItem: _index), itemExtent: 40, backgroundColor: Colors.white, onSelectedItemChanged: (index) { // print(index); _index = index; }, itemBuilder: (context, index) { return Center(child: Text("${_ages[index]}", style: Theme.of(context).textTheme.subtitle1?.copyWith(fontSize: 18.0),)); }, childCount: _ages.length, )), ), ], ), ), ); }); } _showMetDialog(String title) async { await showDialog( context: context, barrierDismissible: true, builder: (BuildContext context) => Dialog( child: Container( padding: EdgeInsets.symmetric(horizontal: 16.0, vertical: 25.0), decoration: circular(), child: Column( mainAxisSize: MainAxisSize.min, children: [ Center( child: Text( title, style: Theme.of(context).textTheme.headline1, ), ), Padding( padding: const EdgeInsets.only(top: 20.0), child: PrimaryButton( width: 120, callback: () { Navigator.maybePop(context); }, content: "知道了"), ), ], ), ), )); } Future _location() async{ AMapLocationOption locationOption = new AMapLocationOption(); AMapFlutterLocation.updatePrivacyShow(true, true); AMapFlutterLocation.updatePrivacyAgree(true); AMapFlutterLocation.setApiKey(KEY_ANDROID, KEY_IOS); ///是否单次定位 locationOption.onceLocation = true; ///是否需要返回逆地理信息 locationOption.needAddress = true; locationOption.fullAccuracyPurposeKey = "AMapLocationScene"; ///设置Android端连续定位的定位间隔 locationOption.locationMode = AMapLocationMode.Hight_Accuracy; locationOption.distanceFilter = 100; locationOption.desiredAccuracy = DesiredAccuracy.Best; ///设置iOS端是否允许系统暂停定位 locationOption.pausesLocationUpdatesAutomatically = false; AMapFlutterLocation _locationPlugin = new AMapFlutterLocation(); ///将定位参数设置给定位插件 _locationPlugin.setLocationOption(locationOption); _locationPlugin.startLocation(); Map result = await _locationPlugin.onLocationChanged().first; print("$result"); _locationPlugin.destroy(); return Location.fromJson(result); } }