diff --git a/.dart_tool/package_config.json b/.dart_tool/package_config.json index bd497aa..969db68 100644 --- a/.dart_tool/package_config.json +++ b/.dart_tool/package_config.json @@ -217,6 +217,12 @@ "packageUri": "lib/", "languageVersion": "2.6" }, + { + "name": "flutter_cupertino_date_picker", + "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/flutter_cupertino_date_picker-1.0.26+2", + "packageUri": "lib/", + "languageVersion": "1.19" + }, { "name": "flutter_native_image", "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/flutter_native_image-0.0.5+2", @@ -229,6 +235,12 @@ "packageUri": "lib/", "languageVersion": "2.0" }, + { + "name": "flutter_plugin_android_lifecycle", + "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/flutter_plugin_android_lifecycle-1.0.9", + "packageUri": "lib/", + "languageVersion": "2.1" + }, { "name": "flutter_screenutil", "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/flutter_screenutil-1.1.0", @@ -301,6 +313,24 @@ "packageUri": "lib/", "languageVersion": "2.0" }, + { + "name": "image_cropper", + "rootUri": "file:///Users/fnuser/.pub-cache/git/Image_Cropper-e32f2264f86a27a2f5d7a7a5e26c6154eaf5798e/", + "packageUri": "lib/", + "languageVersion": "1.20" + }, + { + "name": "image_picker", + "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/image_picker-0.6.7+7", + "packageUri": "lib/", + "languageVersion": "2.1" + }, + { + "name": "image_picker_platform_interface", + "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/image_picker_platform_interface-1.1.0", + "packageUri": "lib/", + "languageVersion": "2.5" + }, { "name": "intl", "rootUri": "file:///Users/fnuser/.pub-cache/hosted/pub.flutter-io.cn/intl-0.16.1", @@ -680,7 +710,7 @@ "languageVersion": "2.1" } ], - "generated": "2020-09-15T07:31:12.840893Z", + "generated": "2020-09-16T07:59:23.044545Z", "generator": "pub", "generatorVersion": "2.7.2" } diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index e72a876..f60a2f8 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -4,11 +4,18 @@ PODS: - Flutter (1.0.0) - flutter_native_image (0.0.1): - Flutter + - flutter_plugin_android_lifecycle (0.0.1): + - Flutter - fluttertoast (0.0.2): - Flutter - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) + - image_cropper (0.0.2): + - Flutter + - TOCropViewController (~> 2.5.2) + - image_picker (0.0.1): + - Flutter - package_info (0.0.1): - Flutter - path_provider (0.0.1): @@ -28,6 +35,7 @@ PODS: - sqflite (0.0.1): - Flutter - FMDB (~> 2.7.2) + - TOCropViewController (2.5.3) - zhiying_base_widget (0.0.1): - Flutter - zhiying_comm (0.0.1): @@ -37,7 +45,10 @@ DEPENDENCIES: - device_info (from `.symlinks/plugins/device_info/ios`) - Flutter (from `Flutter`) - flutter_native_image (from `.symlinks/plugins/flutter_native_image/ios`) + - flutter_plugin_android_lifecycle (from `.symlinks/plugins/flutter_plugin_android_lifecycle/ios`) - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`) + - image_cropper (from `.symlinks/plugins/image_cropper/ios`) + - image_picker (from `.symlinks/plugins/image_picker/ios`) - package_info (from `.symlinks/plugins/package_info/ios`) - path_provider (from `.symlinks/plugins/path_provider/ios`) - path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`) @@ -53,6 +64,7 @@ DEPENDENCIES: SPEC REPOS: trunk: - FMDB + - TOCropViewController EXTERNAL SOURCES: device_info: @@ -61,8 +73,14 @@ EXTERNAL SOURCES: :path: Flutter flutter_native_image: :path: ".symlinks/plugins/flutter_native_image/ios" + flutter_plugin_android_lifecycle: + :path: ".symlinks/plugins/flutter_plugin_android_lifecycle/ios" fluttertoast: :path: ".symlinks/plugins/fluttertoast/ios" + image_cropper: + :path: ".symlinks/plugins/image_cropper/ios" + image_picker: + :path: ".symlinks/plugins/image_picker/ios" package_info: :path: ".symlinks/plugins/package_info/ios" path_provider: @@ -90,8 +108,11 @@ SPEC CHECKSUMS: device_info: d7d233b645a32c40dfdc212de5cf646ca482f175 Flutter: 0e3d915762c693b495b44d77113d4970485de6ec flutter_native_image: 9c0b7451838484458e5b0fae007b86a4c2d4bdfe + flutter_plugin_android_lifecycle: dc0b544e129eebb77a6bfb1239d4d1c673a60a35 fluttertoast: b644586ef3b16f67fae9a1f8754cef6b2d6b634b FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a + image_cropper: 3c16d7651730ffe85897f5a1c4e2547e6b54989a + image_picker: 9c3312491f862b28d21ecd8fdf0ee14e601b3f09 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4 @@ -101,6 +122,7 @@ SPEC CHECKSUMS: shared_preferences_macos: f3f29b71ccbb56bf40c9dd6396c9acf15e214087 shared_preferences_web: 141cce0c3ed1a1c5bf2a0e44f52d31eeb66e5ea9 sqflite: 4001a31ff81d210346b500c55b17f4d6c7589dd0 + TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6 zhiying_base_widget: 00868c0d2723a3a425c18b27204fbc67e3f7e59d zhiying_comm: 0daef4a480f4f4dbea3e11b615f3264aafea924b diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index 04dccaa..27ae0eb 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -162,6 +162,7 @@ 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3DD5E1C6552F1CEFD4C31B18 /* [CP] Embed Pods Frameworks */, + E6B4F9F34A4509DF5D9BF2D8 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -286,6 +287,21 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + E6B4F9F34A4509DF5D9BF2D8 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "[CP] Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -386,6 +402,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -519,6 +536,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", @@ -545,6 +563,7 @@ "$(PROJECT_DIR)/Flutter", ); INFOPLIST_FILE = Runner/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; LIBRARY_SEARCH_PATHS = ( "$(inherited)", diff --git a/example/ios/Runner/Info.plist b/example/ios/Runner/Info.plist index 979cbca..c5bd9d3 100644 --- a/example/ios/Runner/Info.plist +++ b/example/ios/Runner/Info.plist @@ -41,5 +41,19 @@ UIViewControllerBasedStatusBarAppearance + NSCameraUsageDescription + 获取相机权限更换头像或者扫码 + NSContactsUsageDescription + 获取访问通信录权限添加联系人信息 + NSLocationAlwaysUsageDescription + 获取定位权限用于搜索附近的网点和查找附近的油站信息 + NSLocationWhenInUseUsageDescription + 获取定位权限用于搜索附近的网点和查找附近的油站信息 + NSMicrophoneUsageDescription + 获取访问麦克风权限录制语音或视频 + NSPhotoLibraryAddUsageDescription + 获取访问相册权限更换头像 + NSPhotoLibraryUsageDescription + 获取访问相册权限更换头像 diff --git a/lib/pages/mine_detail_page/mine_detail_bloc.dart b/lib/pages/mine_detail_page/mine_detail_bloc.dart new file mode 100644 index 0000000..feb7750 --- /dev/null +++ b/lib/pages/mine_detail_page/mine_detail_bloc.dart @@ -0,0 +1,83 @@ +import 'dart:async'; +import 'dart:io'; + +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:path/path.dart'; +import 'package:zhiying_base_widget/pages/mine_detail_page/models/mine_detail_model.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class MineDetailBloc extends BlocBase { + MineDetailModel _user; + + StreamController _userController = + StreamController(); + + Stream get outData => _userController.stream; + + @override + void dispose() { + _userController.close(); + _userController = null; + } + + void loadData() { + NetUtil.request('/api/v1/user/info', method: NetMethod.GET, + onCache: (data) { + if (_user == null) _loadData(data); + }, onSuccess: (data) { + _loadData(data); + }); + } + + void _loadData(dynamic data) { + _user = MineDetailModel.fromJson(Map.from(data)); + + _userController.add(_user); + } + + /* 更新用户信息 + nickname 昵称 + gender 性别(1女2男3未知) + birthday 生日(时间戳) + * */ + void updateUser({String nickname, String gender, String birthday}) { + Map params = Map(); + if (nickname != null && nickname != '') { + params['nickname'] = nickname; + } + if (gender != null && gender != '') { + params['gender'] = gender; + } + if (birthday != null && birthday != '') { + params['birthday'] = birthday; + } + NetUtil.request('/api/v1/user/info', + method: NetMethod.POST, + params: params, + onCache: (data) {}, onSuccess: (data) { + Fluttertoast.showToast(msg: '修改成功'); + loadData(); + }); + } + + void uploadAvatar(File file) async { + List originBytes = await file.readAsBytes(); + print('原图大小:' + originBytes.length.toString() + 'byte'); + print('原图大小:' + basename(file.path)); + + Map params = Map(); + params['dir'] = 'avatar'; + params['file_size'] = originBytes.length; + params['file_name'] = basename(file.path); + NetUtil.request('/api/v1/file/upload', + method: NetMethod.PUT, + params: params, + onCache: (data) {}, onSuccess: (data) { + String method = data['method']; + String host = data['host']; + String key = data['key']; + String token = data['token']; + }); + } +} diff --git a/lib/pages/mine_detail_page/mine_detail_page.dart b/lib/pages/mine_detail_page/mine_detail_page.dart new file mode 100644 index 0000000..c48e487 --- /dev/null +++ b/lib/pages/mine_detail_page/mine_detail_page.dart @@ -0,0 +1,347 @@ +import 'dart:io'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:fluttertoast/fluttertoast.dart'; +import 'package:image_cropper/image_cropper.dart'; +import 'package:image_picker/image_picker.dart'; +import 'package:intl/intl.dart'; +import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_bloc.dart'; +import 'package:zhiying_base_widget/pages/mine_detail_page/models/mine_detail_model.dart'; +import 'package:zhiying_base_widget/widgets/others/action_date_alert/action_date_alert.dart'; +import 'package:zhiying_base_widget/widgets/others/action_list_alert/action_list_alert.dart'; +import 'package:zhiying_base_widget/widgets/others/action_selected_alert/action_selected_alert.dart'; +import 'package:zhiying_comm/util/base_bloc.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class MineDetailPage extends StatefulWidget { + @override + _MineDetailPageState createState() => _MineDetailPageState(); +} + +class _MineDetailPageState extends State { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color(0xfff9f9f9), + appBar: _createNav(), + body: SafeArea( + child: BlocProvider( + bloc: MineDetailBloc(), + child: _MineDetailContainer(), + ), + ), + ); + } + + // 导航栏 + Widget _createNav() { + return CupertinoNavigationBar( + border: Border( + bottom: BorderSide( + width: 0.0, // One physical pixel. + style: BorderStyle.none, + ), + ), + backgroundColor: Colors.white, + leading: Navigator.canPop(context) + ? GestureDetector( + child: Container( + padding: EdgeInsets.zero, + child: Icon( + Icons.arrow_back_ios, + size: 20, + ), + ), + onTap: () { + if (Navigator.canPop(context)) { + Navigator.pop(context); + } + }, + ) + : Container(), + middle: Text( + '个人信息', + style: TextStyle( + fontSize: 15, + color: Color(0xff333333), + ), + ), + ); + } +} + +class _MineDetailContainer extends StatefulWidget { + @override + _MineDetailContainerState createState() => _MineDetailContainerState(); +} + +class _MineDetailContainerState extends State<_MineDetailContainer> { + MineDetailBloc _bloc; + TextEditingController _nickController = TextEditingController(); + + @override + void initState() { + _bloc = BlocProvider.of(context); + _bloc.loadData(); + super.initState(); + } + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: _bloc.outData, + builder: (BuildContext context, AsyncSnapshot snapshot) { + MineDetailModel user = snapshot.data; + int birthday = int.tryParse(user?.birthday) ?? 0; + int registTime = int.tryParse(user?.registerTime) ?? 0; + _nickController.text = user?.nickname ?? ''; + + return SingleChildScrollView( + child: Column( + children: [ + _creteHeader(user, onTap: () { + _selectImage(); + }), + _createInput('昵称', _nickController, onTap: () {}), + _createLine(), + _createItem('性别', user?.gender, onTap: () { + _selectSex(); + }), + _createLine(), + _createItem( + '出生日期', + birthday > 0 + ? DateFormat('yyyy-MM-dd').format( + DateTime.fromMillisecondsSinceEpoch( + birthday * 1000)) + : user?.birthday ?? '', onTap: () { + _selectBrithday(); + }), + _createLine(), + _createItem( + '注册时间', + registTime > 0 + ? DateFormat('yyyy-MM-dd').format( + DateTime.fromMillisecondsSinceEpoch( + registTime * 1000)) + : user?.registerTime ?? ''), + ], + ), + ); + }); + } + + // 头像 + Widget _creteHeader(MineDetailModel user, {VoidCallback onTap}) { + return GestureDetector( + child: Container( + height: 140, + width: double.infinity, + margin: EdgeInsets.only(top: 5), + color: Colors.white, + child: Column( + children: [ + Container( + width: 80, + height: 80, + margin: EdgeInsets.only(top: 15), + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(40), + color: Colors.black12), + child: ClipRRect( + borderRadius: BorderRadius.circular(40), + child: CachedNetworkImage( + imageUrl: user?.avatar ?? '', + fit: BoxFit.cover, + ), + ), + ), + Padding( + padding: const EdgeInsets.all(6.0), + child: Text( + user == null ? '' : '点击更换头像', + style: TextStyle(fontSize: 11, color: Color(0xff999999)), + ), + ) + ], + ), + ), + onTap: onTap, + ); + } + + Widget _createItem(String title, String desc, {VoidCallback onTap}) { + return GestureDetector( + child: Container( + padding: EdgeInsets.only(left: 12.5, right: 12.5), + height: 48, + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Text( + title ?? '', + style: TextStyle( + fontSize: 13, + color: Color(0xff333333), + fontWeight: FontWeight.bold), + ), + ), + Text( + desc ?? '', + style: TextStyle( + fontSize: 13, + color: Color(0xff999999), + ), + ), + onTap == null + ? Container() + : Icon( + Icons.arrow_forward_ios, + size: 12, + color: Color(0xff999999), + ) + ], + ), + ), + onTap: onTap, + ); + } + + Widget _createInput(String title, TextEditingController controller, + {VoidCallback onTap}) { + return GestureDetector( + child: Container( + padding: EdgeInsets.only(left: 12.5, right: 12.5), + height: 48, + color: Colors.white, + child: Row( + children: [ + Expanded( + child: Text( + title ?? '', + style: TextStyle( + fontSize: 13, + color: Color(0xff333333), + fontWeight: FontWeight.bold), + ), + ), + Expanded( + child: CupertinoTextField( + decoration: BoxDecoration(color: Colors.transparent), + textInputAction: TextInputAction.done, + controller: controller, + textAlign: TextAlign.right, + placeholder: '输入昵称', + style: TextStyle( + fontSize: 13, + color: Color(0xff999999), + ), + onSubmitted: (value) { + if (value == null || value == '') { + Fluttertoast.showToast(msg: '昵称不为空'); + return; + } + _bloc.updateUser(nickname: value); + }, + ), + ), + onTap == null + ? Container() + : Icon( + Icons.arrow_forward_ios, + size: 12, + color: Color(0xff999999), + ) + ], + ), + ), + onTap: onTap, + ); + } + + Widget _createLine() { + return Container( + width: double.infinity, + height: 0.5, + margin: EdgeInsets.only(left: 12.5, right: 12.5), + color: Color(0xfff4f4f4), + ); + } + + void _selectImage() async { + final picker = ImagePicker(); + PickedFile file; + int index = await showModalBottomSheet( + context: context, + builder: (context) { + return ActionSelectedAlert( + // title: '拍照/选择图片', + actions: ['拍照', '从相册选择图片'], + ); + }, + isScrollControlled: false, + backgroundColor: Colors.transparent); + if (index != null) { + if (index == 0) { + file = await picker.getImage(source: ImageSource.camera); + } else { + file = await picker.getImage(source: ImageSource.gallery); + } + + if (file == null) return; + File cropperFile = await ImageCropper.cropImage( + sourcePath: file.path, + aspectRatioPresets: [ + CropAspectRatioPreset.square, + ], + androidUiSettings: AndroidUiSettings( + toolbarTitle: '图片剪裁', + toolbarColor: HexColor.fromHex('#E52425'), + toolbarWidgetColor: Colors.white, + initAspectRatio: CropAspectRatioPreset.original, + lockAspectRatio: true), + iosUiSettings: IOSUiSettings( + minimumAspectRatio: 1.0, aspectRatioLockEnabled: true)); + File resultFile = await EncodeUtil.compressImage(cropperFile, 800); + _bloc.uploadAvatar(resultFile); + } + } + + // 选择性别 + void _selectSex() async { + int index = await showModalBottomSheet( + context: context, + builder: (context) { + return ActionListAlert( + title: '选择性别', + actions: ['女', '男'], + ); + }, + isScrollControlled: false, + backgroundColor: Colors.transparent); + if (index != null) { + print(index); + _bloc.updateUser(gender: index == 0 ? '1' : '2'); + } + } + + void _selectBrithday() async { + DateTime dateTime = await showModalBottomSheet( + context: context, + builder: (context) { + return ActionDateAlert( + title: '选择出生日期', + ); + }, + isScrollControlled: false, + backgroundColor: Colors.transparent); + if (dateTime != null) { + String timeStamp = + (dateTime.millisecondsSinceEpoch / 1000).ceil().toString(); + _bloc.updateUser(birthday: timeStamp); + } + } +} diff --git a/lib/pages/mine_detail_page/models/mine_detail_model.dart b/lib/pages/mine_detail_page/models/mine_detail_model.dart new file mode 100644 index 0000000..63386f8 --- /dev/null +++ b/lib/pages/mine_detail_page/models/mine_detail_model.dart @@ -0,0 +1,34 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'mine_detail_model.g.dart'; + +@JsonSerializable() +class MineDetailModel extends Object { + @JsonKey(name: 'avatar') + String avatar; + + @JsonKey(name: 'nickname') + String nickname; + + @JsonKey(name: 'gender') + String gender; + + @JsonKey(name: 'birthday') + String birthday; + + @JsonKey(name: 'register_time') + String registerTime; + + MineDetailModel( + this.avatar, + this.nickname, + this.gender, + this.birthday, + this.registerTime, + ); + + factory MineDetailModel.fromJson(Map srcJson) => + _$MineDetailModelFromJson(srcJson); + + Map toJson() => _$MineDetailModelToJson(this); +} diff --git a/lib/pages/mine_detail_page/models/mine_detail_model.g.dart b/lib/pages/mine_detail_page/models/mine_detail_model.g.dart new file mode 100644 index 0000000..6caa278 --- /dev/null +++ b/lib/pages/mine_detail_page/models/mine_detail_model.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'mine_detail_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MineDetailModel _$MineDetailModelFromJson(Map json) { + return MineDetailModel( + json['avatar'] as String, + json['nickname'] as String, + json['gender'] as String, + json['birthday'] as String, + json['register_time'] as String, + ); +} + +Map _$MineDetailModelToJson(MineDetailModel instance) => + { + 'avatar': instance.avatar, + 'nickname': instance.nickname, + 'gender': instance.gender, + 'birthday': instance.birthday, + 'register_time': instance.registerTime, + }; diff --git a/lib/register.dart b/lib/register.dart index 1bee69e..218d02f 100644 --- a/lib/register.dart +++ b/lib/register.dart @@ -1,5 +1,6 @@ import 'package:zhiying_base_widget/pages/home_page/home_page.dart'; import 'package:zhiying_base_widget/pages/main_page/main_page.dart'; +import 'package:zhiying_base_widget/pages/mine_detail_page/mine_detail_page.dart'; import 'package:zhiying_base_widget/pages/wallet_page/wallet_page.dart'; import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_creater.dart'; import 'package:zhiying_base_widget/widgets/home/home_banner/home_banner_widget.dart'; @@ -35,6 +36,9 @@ class BaseWidgetRegister { // PageFactory.regist('login_quick', (model) => LoginQuickPage(model)); // PageFactory.regist('login_account', (model) => LoginAccountPage(model)); // PageFactory.regist('login_invite', (model) => LoginInvitePage()); + + PageFactory.regist( + 'pub.flutter.profile_settings', (model) => MineDetailPage()); } // 注册控件 diff --git a/lib/widgets/mine/mine_data/mine_data_widget.dart b/lib/widgets/mine/mine_data/mine_data_widget.dart index 15971c4..799f3e0 100644 --- a/lib/widgets/mine/mine_data/mine_data_widget.dart +++ b/lib/widgets/mine/mine_data/mine_data_widget.dart @@ -12,11 +12,10 @@ class MineDataWidget extends StatelessWidget { Map _json; MineDataModel _style; - MineDataWidget( - this.profile, - this.data, { - Key key, - }) : super(key: key) { + MineDataWidget(this.profile, + this.data, { + Key key, + }) : super(key: key) { String d = data['data']; _json = convert.jsonDecode(d); _style = MineDataModel.fromJson(Map.from(_json)); @@ -87,7 +86,11 @@ class MineDataWidget extends StatelessWidget { fontWeight: FontWeight.w800, color: HexColor.fromHex( _style.accumulatedEarningsNameColor), - fontFamily: 'Din', + fontFamily: 'Din-Bold' + '' + '' + '' + '', package: 'zhiying_base_widget', ), ), @@ -218,7 +221,7 @@ class MineDataWidget extends StatelessWidget { style: TextStyle( fontSize: 18, color: HexColor.fromHex(_style.gridViewValueColor), - fontFamily: 'Din', + fontFamily: 'Din-Bold', package: 'zhiying_base_widget'), ), ), @@ -250,7 +253,7 @@ class MineDataWidget extends StatelessWidget { style: TextStyle( fontSize: 12, color: HexColor.fromHex(_style.gridViewValueColor), - fontFamily: 'Din', + fontFamily: 'Din-Bold', package: 'zhiying_base_widget'), ), ), diff --git a/lib/widgets/mine/mine_header/mine_header.dart b/lib/widgets/mine/mine_header/mine_header.dart index b80ada6..bcf0108 100644 --- a/lib/widgets/mine/mine_header/mine_header.dart +++ b/lib/widgets/mine/mine_header/mine_header.dart @@ -28,6 +28,16 @@ class _MineHeaderState extends State { @override Widget build(BuildContext context) { +// return Consumer(builder: (context, user, child) { +// print('user ${user.toString()}'); +// if (user == null) { +// return MineStaticContainer(widget.data); +// } +// return BlocProvider( +// bloc: MineHeaderBloc(), +// child: MineHeaderContainer(widget.data), +// ); +// }); if (_isSketelon) { Provider.of(context).getUserInfoModel().then((user) { setState(() { diff --git a/lib/widgets/others/action_date_alert/action_date_alert.dart b/lib/widgets/others/action_date_alert/action_date_alert.dart new file mode 100644 index 0000000..4f7e4de --- /dev/null +++ b/lib/widgets/others/action_date_alert/action_date_alert.dart @@ -0,0 +1,107 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cupertino_date_picker/flutter_cupertino_date_picker.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class ActionDateAlert extends StatefulWidget { + final String title; + final TextStyle normalStyle; + final TextStyle selectedStyle; + + const ActionDateAlert({ + Key key, + this.title, + this.normalStyle, + this.selectedStyle, + }) : super(key: key); + + @override + State createState() => _ActionDateAlert(); +} + +class _ActionDateAlert extends State { + DateTime _dateTime = DateTime.now(); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: GestureDetector( + child: Column( + children: [ + Expanded( + child: Container(), + ), + Container( + width: double.infinity, + height: 250, + margin: EdgeInsets.all(0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10))), + child: Column( + children: [ + widget.title == null || widget.title == '' + ? Container() + : Container( + height: 44, + child: Row( + children: [ + FlatButton( + child: Text('取消'), + onPressed: () { + Navigator.pop(context); + }, + ), + Expanded( + child: Center( + child: Text( + widget.title, + style: TextStyle( + fontSize: 13, + color: Colors.black.withAlpha(180)), + ), + ), + ), + FlatButton( + child: Text( + '完成', + style: TextStyle( + color: HexColor.fromHex('#E52425')), + ), + onPressed: () { + Navigator.pop(context, _dateTime); + }, + ), + ], + )), + Expanded( + child: _createContent(context), + ) + ], + ), + ), + ], + ), + onTap: () { + Navigator.pop(context); + }, + ), + ); + } + + Widget _createContent(BuildContext context) { + return DatePickerWidget( + initialDateTime: _dateTime, + onChange: (dataTime, list) { + _dateTime = dataTime; + }, + pickerTheme: DateTimePickerTheme( + pickerHeight: 180, + title: Container(), + ), + ); + } +} diff --git a/lib/widgets/others/action_list_alert/action_list_alert.dart b/lib/widgets/others/action_list_alert/action_list_alert.dart new file mode 100644 index 0000000..42842ce --- /dev/null +++ b/lib/widgets/others/action_list_alert/action_list_alert.dart @@ -0,0 +1,128 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class ActionListAlert extends StatefulWidget { + final String title; + final List actions; + final TextStyle normalStyle; + final TextStyle selectedStyle; + + const ActionListAlert( + {Key key, this.title, this.actions, this.normalStyle, this.selectedStyle}) + : super(key: key); + + @override + State createState() => _ActionListAlert(); +} + +class _ActionListAlert extends State { + int _currentIndex = 0; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: GestureDetector( + child: Column( + children: [ + Expanded( + child: Container(), + ), + Container( + width: double.infinity, + height: 250, + margin: EdgeInsets.all(0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10))), + child: Column( + children: [ + widget.title == null || widget.title == '' + ? Container() + : Container( + height: 44, + child: Row( + children: [ + FlatButton( + child: Text('取消'), + onPressed: () { + Navigator.pop(context); + }, + ), + Expanded( + child: Center( + child: Text( + widget.title, + style: TextStyle( + fontSize: 13, + color: Colors.black.withAlpha(180)), + ), + ), + ), + FlatButton( + child: Text( + '完成', + style: TextStyle( + color: HexColor.fromHex('#E52425')), + ), + onPressed: () { + Navigator.pop(context, _currentIndex); + }, + ), + ], + )), + Expanded( + child: _createContent(context), + ) + ], + ), + ), + ], + ), + onTap: () { + Navigator.pop(context); + }, + ), + ); + } + + Widget _createContent(BuildContext context) { + List widgets = List(); + + TextStyle normalStyle = widget.normalStyle ?? + TextStyle(fontSize: 12, color: HexColor.fromHex('#7f7f7f')); + TextStyle selectedStyle = widget.selectedStyle ?? + TextStyle(fontSize: 14, color: HexColor.fromHex('#E52425')); + + for (int index = 0; index < widget.actions.length; index++) { + int i = index; + widgets.add(Column( + children: [ + Container( + // color: HexColor.random(), + height: 40, + child: Center( + child: Text( + widget.actions[index], + style: i == _currentIndex ? selectedStyle : normalStyle, + ), + ), + ) + ], + )); + } + return CupertinoPicker( + backgroundColor: Colors.white, + children: widgets, + itemExtent: 40, + onSelectedItemChanged: (int index) { + setState(() { + _currentIndex = index; + }); + }, + ); + } +} diff --git a/lib/widgets/others/action_selected_alert/action_selected_alert.dart b/lib/widgets/others/action_selected_alert/action_selected_alert.dart new file mode 100644 index 0000000..e1d05cf --- /dev/null +++ b/lib/widgets/others/action_selected_alert/action_selected_alert.dart @@ -0,0 +1,125 @@ +import 'package:flutter/material.dart'; +import 'package:zhiying_comm/zhiying_comm.dart'; + +class ActionSelectedAlert extends StatelessWidget { + final String title; + final List actions; + + const ActionSelectedAlert({Key key, this.title, this.actions}) + : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Colors.transparent, + body: GestureDetector( + child: Container( + width: double.infinity, + // height: double.infinity, + color: Colors.transparent, + child: Container( + width: double.infinity, + // height: double.infinity, + // color: Colors.red, + child: Column( + children: [ + Expanded( + child: Container(), + ), + Container( + width: double.infinity, + margin: EdgeInsets.all(0), + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10), + topRight: Radius.circular(10))), + child: Column( + children: [ + title == null || title == '' + ? Container() + : Container( + height: 44, + child: Center( + child: Text( + title, + style: TextStyle( + fontSize: 13, + color: Colors.black.withAlpha(180)), + ), + ), + ), + title == null || title == '' || actions.length == 0 + ? Container() + : Container( + width: double.infinity, + height: 0.5, + color: HexColor.fromHex('#F2F2F2'), + ), + _createContent(context), + Container( + width: double.infinity, + height: 4, + color: HexColor.fromHex('#F2F2F2'), + ), + SafeArea( + child: Container( + width: double.infinity, + margin: EdgeInsets.all(0), + color: Colors.white, + height: 56, + child: Center( + child: Text( + '取消', + style: TextStyle( + fontSize: 17, color: Colors.black), + ), + ), + ), + ), + ], + ), + ), + ], + ), + )), + onTap: () { + Navigator.pop(context); + }, + ), + ); + } + + Widget _createContent(BuildContext context) { + List widgets = List(); + for (int index = 0; index < actions.length; index++) { + int i = index; + widgets.add(Column( + children: [ + GestureDetector( + child: Container( + color: Colors.transparent, + height: 54, + child: Center( + child: Text( + actions[index], + style: TextStyle(fontSize: 17, color: Colors.black), + ), + ), + ), + onTap: () { + print(i); + Navigator.pop(context, i); + }, + ), + Container( + width: double.infinity, + height: 0.5, + color: HexColor.fromHex('#F2F2F2'), + ) + ], + )); + } + return Column(children: widgets); + } +} diff --git a/pubspec.yaml b/pubspec.yaml index c521220..cb7523d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,11 +11,16 @@ dependencies: flutter: sdk: flutter - flutter_swiper : ^1.1.6 + flutter_swiper: ^1.1.6 bloc: ^4.0.0 event_bus: ^1.1.1 pull_to_refresh: ^1.6.1 - + flutter_cupertino_date_picker: ^1.0.26+2 + image_picker: ^0.6.7+3 + image_cropper: + git: + url: 'http://192.168.0.138:3000/FnuoOS_Flutter_Components/Image_Cropper.git' + ref: '1.2.3+1' dev_dependencies: flutter_test: @@ -58,10 +63,14 @@ flutter: # list giving the asset and other descriptors for the font. For # example: fonts: - - family: Din + - family: Din-Bold fonts: - asset: assets/fonts/DIN-Bold.otf + - family: Din-Medium + fonts: - asset: assets/fonts/DIN-Medium.otf + - family: Din + fonts: - asset: assets/fonts/DIN-Regular.otf #