Commit c948a9eac63212b287c5ece7f034e0fe877932eb

Authored by liangchengyou
1 parent 67d028e7

feat:个人信息更改模块功能

assets/images/alter.png 0 → 100644

40.7 KB

assets/images/intowow.png 0 → 100644

26.9 KB

assets/images/oninto.png 0 → 100644

25.6 KB

ios/Podfile
@@ -43,5 +43,52 @@ end @@ -43,5 +43,52 @@ end
43 post_install do |installer| 43 post_install do |installer|
44 installer.pods_project.targets.each do |target| 44 installer.pods_project.targets.each do |target|
45 flutter_additional_ios_build_settings(target) 45 flutter_additional_ios_build_settings(target)
  46 + target.build_configurations.each do |config|
  47 + config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
  48 + '$(inherited)',
  49 +
  50 + ## dart: PermissionGroup.calendar
  51 + # 'PERMISSION_EVENTS=1',
  52 +
  53 + ## dart: PermissionGroup.reminders
  54 + # 'PERMISSION_REMINDERS=1',
  55 +
  56 + ## dart: PermissionGroup.contacts
  57 + # 'PERMISSION_CONTACTS=1',
  58 +
  59 + ## dart: PermissionGroup.camera
  60 + 'PERMISSION_CAMERA=1',
  61 +
  62 + ## dart: PermissionGroup.microphone
  63 + 'PERMISSION_MICROPHONE=1',
  64 +
  65 + ## dart: PermissionGroup.speech
  66 + # 'PERMISSION_SPEECH_RECOGNIZER=1',
  67 +
  68 + ## dart: PermissionGroup.photos
  69 + 'PERMISSION_PHOTOS=1',
  70 +
  71 + ## dart: [PermissionGroup.location, PermissionGroup.locationAlways, PermissionGroup.locationWhenInUse]
  72 + # 'PERMISSION_LOCATION=1',
  73 +
  74 + ## dart: PermissionGroup.notification
  75 + # 'PERMISSION_NOTIFICATIONS=1',
  76 +
  77 + ## dart: PermissionGroup.mediaLibrary
  78 + # 'PERMISSION_MEDIA_LIBRARY=1',
  79 +
  80 + ## dart: PermissionGroup.sensors
  81 + # 'PERMISSION_SENSORS=1',
  82 +
  83 + ## dart: PermissionGroup.bluetooth
  84 + # 'PERMISSION_BLUETOOTH=1',
  85 +
  86 + ## dart: PermissionGroup.appTrackingTransparency
  87 + # 'PERMISSION_APP_TRACKING_TRANSPARENCY=1',
  88 +
  89 + ## dart: PermissionGroup.criticalAlerts
  90 + # 'PERMISSION_CRITICAL_ALERTS=1'
  91 + ]
  92 + end
46 end 93 end
47 end 94 end
ios/Runner/Info.plist
@@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
24 <string>????</string> 24 <string>????</string>
25 <key>CFBundleVersion</key> 25 <key>CFBundleVersion</key>
26 <string>$(FLUTTER_BUILD_NUMBER)</string> 26 <string>$(FLUTTER_BUILD_NUMBER)</string>
  27 + <key>LSApplicationCategoryType</key>
  28 + <string></string>
27 <key>LSRequiresIPhoneOS</key> 29 <key>LSRequiresIPhoneOS</key>
28 <true/> 30 <true/>
29 <key>NSAppTransportSecurity</key> 31 <key>NSAppTransportSecurity</key>
@@ -31,6 +33,8 @@ @@ -31,6 +33,8 @@
31 <key>NSAllowsArbitraryLoads</key> 33 <key>NSAllowsArbitraryLoads</key>
32 <true/> 34 <true/>
33 </dict> 35 </dict>
  36 + <key>NSCameraUsageDescription</key>
  37 + <string>需要访问相机完成拍照</string>
34 <key>NSMicrophoneUsageDescription</key> 38 <key>NSMicrophoneUsageDescription</key>
35 <string>需要获取录音完成后续功能</string> 39 <string>需要获取录音完成后续功能</string>
36 <key>NSPhotoLibraryUsageDescription</key> 40 <key>NSPhotoLibraryUsageDescription</key>
lib/app/app.dart
@@ -7,6 +7,7 @@ import &#39;package:responsive_framework/responsive_breakpoints.dart&#39;; @@ -7,6 +7,7 @@ import &#39;package:responsive_framework/responsive_breakpoints.dart&#39;;
7 import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart'; 7 import 'package:wow_english/common/blocs/cachebloc/cache_bloc.dart';
8 import 'package:wow_english/common/widgets/hide_keyboard_widget.dart'; 8 import 'package:wow_english/common/widgets/hide_keyboard_widget.dart';
9 import 'package:wow_english/pages/tab/blocs/tab_bloc.dart'; 9 import 'package:wow_english/pages/tab/blocs/tab_bloc.dart';
  10 +import 'package:wow_english/pages/user/bloc/user_bloc.dart';
10 import 'package:wow_english/route/route.dart'; 11 import 'package:wow_english/route/route.dart';
11 12
12 class App extends StatelessWidget { 13 class App extends StatelessWidget {
@@ -20,6 +21,7 @@ class App extends StatelessWidget { @@ -20,6 +21,7 @@ class App extends StatelessWidget {
20 providers: [ 21 providers: [
21 BlocProvider<TabBloc>(create: (_) => TabBloc()), 22 BlocProvider<TabBloc>(create: (_) => TabBloc()),
22 BlocProvider<CacheBloc>(create: (_) => CacheBloc()), 23 BlocProvider<CacheBloc>(create: (_) => CacheBloc()),
  24 + BlocProvider<UserBloc>(create: (_) => UserBloc()),
23 ], 25 ],
24 child: HideKeyboard( 26 child: HideKeyboard(
25 child: MaterialApp( 27 child: MaterialApp(
lib/pages/home/widgets/home_tab_header_widget.dart
1 import 'package:flutter/material.dart'; 1 import 'package:flutter/material.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
2 import 'package:flutter_screenutil/flutter_screenutil.dart'; 3 import 'package:flutter_screenutil/flutter_screenutil.dart';
3 import 'package:wow_english/common/core/user_util.dart'; 4 import 'package:wow_english/common/core/user_util.dart';
4 import 'package:wow_english/common/extension/string_extension.dart'; 5 import 'package:wow_english/common/extension/string_extension.dart';
  6 +import 'package:wow_english/pages/user/bloc/user_bloc.dart';
5 import 'package:wow_english/utils/color_util.dart'; 7 import 'package:wow_english/utils/color_util.dart';
6 import 'package:wow_english/utils/image_util.dart'; 8 import 'package:wow_english/utils/image_util.dart';
7 9
@@ -26,89 +28,93 @@ class HomeTabHeaderWidget extends StatelessWidget { @@ -26,89 +28,93 @@ class HomeTabHeaderWidget extends StatelessWidget {
26 28
27 @override 29 @override
28 Widget build(BuildContext context) { 30 Widget build(BuildContext context) {
29 - return Container(  
30 - height: 45,  
31 - width: double.infinity,  
32 - color: HexColor(themColor??''),  
33 - padding: EdgeInsets.symmetric(horizontal: 9.5.w),  
34 - child: Row(  
35 - children: [  
36 - ScreenUtil().bottomBarHeight.horizontalSpace,  
37 - GestureDetector(  
38 - onTap: () => actionTap?.call(HeaderActionType.user),  
39 - child: Container(  
40 - decoration: BoxDecoration(  
41 - border: Border.all(  
42 - width: 1.0,  
43 - color: const Color(0xFF140C10), 31 + return BlocBuilder<UserBloc,UserState>(
  32 + builder: (context,state) {
  33 + return Container(
  34 + height: 45,
  35 + width: double.infinity,
  36 + color: HexColor(themColor??''),
  37 + padding: EdgeInsets.symmetric(horizontal: 9.5.w),
  38 + child: Row(
  39 + children: [
  40 + ScreenUtil().bottomBarHeight.horizontalSpace,
  41 + GestureDetector(
  42 + onTap: () => actionTap?.call(HeaderActionType.user),
  43 + child: Container(
  44 + decoration: BoxDecoration(
  45 + border: Border.all(
  46 + width: 1.0,
  47 + color: const Color(0xFF140C10),
  48 + ),
  49 + borderRadius: BorderRadius.circular(21),
  50 + ),
  51 + child: CircleAvatar(
  52 + radius: 21,
  53 + backgroundImage: ImageUtil.getImageProviderOnDefault(UserUtil.getUser()?.avatarUrl),
  54 + ),
  55 + ),
44 ), 56 ),
45 - borderRadius: BorderRadius.circular(21),  
46 - ),  
47 - child: CircleAvatar(  
48 - radius: 21,  
49 - backgroundImage: ImageUtil.getImageProviderOnDefault(UserUtil.getUser()?.avatarUrl),  
50 - ),  
51 - ),  
52 - ),  
53 - GestureDetector(  
54 - onTap: () {  
55 - if (actionTap != null) {  
56 - actionTap!(HeaderActionType.user);  
57 - }  
58 - },  
59 - child: Container(  
60 - margin: const EdgeInsets.only(left: 7),  
61 - padding: const EdgeInsets.all(4.0),  
62 - decoration: BoxDecoration(  
63 - color: Colors.white,  
64 - borderRadius: BorderRadius.circular(2),  
65 - border: Border.all(width: 1.0, color: const Color(0xFF140C10), style: BorderStyle.solid),  
66 - ),  
67 - child: Text(  
68 - UserUtil.getUser()?.name ?? '未登录',  
69 - style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp),  
70 - ),  
71 - ),  
72 - ),  
73 - 20.horizontalSpace,  
74 - const Expanded(  
75 - child: Text(  
76 - 'learn wow',  
77 - textAlign: TextAlign.left,  
78 - style: TextStyle(color: Colors.white, fontSize: 30.0),  
79 - )),  
80 - IconButton(  
81 - onPressed: () {  
82 - if (actionTap != null) {  
83 - actionTap!(HeaderActionType.video);  
84 - }  
85 - },  
86 - icon: Image.asset('video'.assetPng)),  
87 - IconButton(  
88 - onPressed: () {  
89 - if (actionTap != null) {  
90 - actionTap!(HeaderActionType.phase);  
91 - }  
92 - },  
93 - icon: Image.asset('home'.assetPng)),  
94 - IconButton(  
95 - onPressed: () {  
96 - if (actionTap != null) {  
97 - actionTap!(HeaderActionType.listen);  
98 - }  
99 - },  
100 - icon: Image.asset('listen'.assetPng)),  
101 - // IconButton(  
102 - // onPressed: (){  
103 - // if(actionTap != null) {  
104 - // actionTap!(HeaderActionType.shop);  
105 - // }  
106 - // },  
107 - // icon: Image.asset('shop'.assetPng)  
108 - // ),  
109 - ScreenUtil().bottomBarHeight.horizontalSpace,  
110 - ],  
111 - ) 57 + GestureDetector(
  58 + onTap: () {
  59 + if (actionTap != null) {
  60 + actionTap!(HeaderActionType.user);
  61 + }
  62 + },
  63 + child: Container(
  64 + margin: const EdgeInsets.only(left: 7),
  65 + padding: const EdgeInsets.all(4.0),
  66 + decoration: BoxDecoration(
  67 + color: Colors.white,
  68 + borderRadius: BorderRadius.circular(2),
  69 + border: Border.all(width: 1.0, color: const Color(0xFF140C10), style: BorderStyle.solid),
  70 + ),
  71 + child: Text(
  72 + UserUtil.getUser()?.name ?? '未登录',
  73 + style: TextStyle(color: const Color(0xFF333333), fontSize: 16.sp),
  74 + ),
  75 + ),
  76 + ),
  77 + 20.horizontalSpace,
  78 + const Expanded(
  79 + child: Text(
  80 + 'learn wow',
  81 + textAlign: TextAlign.left,
  82 + style: TextStyle(color: Colors.white, fontSize: 30.0),
  83 + )),
  84 + IconButton(
  85 + onPressed: () {
  86 + if (actionTap != null) {
  87 + actionTap!(HeaderActionType.video);
  88 + }
  89 + },
  90 + icon: Image.asset('video'.assetPng)),
  91 + IconButton(
  92 + onPressed: () {
  93 + if (actionTap != null) {
  94 + actionTap!(HeaderActionType.phase);
  95 + }
  96 + },
  97 + icon: Image.asset('home'.assetPng)),
  98 + IconButton(
  99 + onPressed: () {
  100 + if (actionTap != null) {
  101 + actionTap!(HeaderActionType.listen);
  102 + }
  103 + },
  104 + icon: Image.asset('listen'.assetPng)),
  105 + // IconButton(
  106 + // onPressed: (){
  107 + // if(actionTap != null) {
  108 + // actionTap!(HeaderActionType.shop);
  109 + // }
  110 + // },
  111 + // icon: Image.asset('shop'.assetPng)
  112 + // ),
  113 + ScreenUtil().bottomBarHeight.horizontalSpace,
  114 + ],
  115 + )
  116 + );
  117 + },
112 ); 118 );
113 } 119 }
114 } 120 }
lib/pages/user/bloc/user_bloc.dart
@@ -33,13 +33,13 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -33,13 +33,13 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
33 } 33 }
34 34
35 void _updateUser(UserUpdate event, Emitter<UserState> emitter) async { 35 void _updateUser(UserUpdate event, Emitter<UserState> emitter) async {
36 - Log.d('_updateUser, event: ${event.type}, emitter.isDone: ${emitter.isDone}, text=${modifyTextController.text}'); 36 + Log.d('_updateUser, event: ${event.type}, emitter.isDone: ${emitter.isDone}, text=${event.content}');
37 UserEntity user = UserUtil.getUser()!; 37 UserEntity user = UserUtil.getUser()!;
38 switch (event.type) { 38 switch (event.type) {
39 case ModifyUserInformationType.avatar: 39 case ModifyUserInformationType.avatar:
40 break; 40 break;
41 case ModifyUserInformationType.name: 41 case ModifyUserInformationType.name:
42 - String name = modifyTextController.text; 42 + String name = event.content;
43 try { 43 try {
44 await UserDao.updateUserInfoField(name: name); 44 await UserDao.updateUserInfoField(name: name);
45 // 修改成功,更新本地缓存及UI 45 // 修改成功,更新本地缓存及UI
@@ -54,7 +54,7 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -54,7 +54,7 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
54 try { 54 try {
55 int age; 55 int age;
56 try { 56 try {
57 - age = modifyTextController.text as int; 57 + age = int.parse(event.content);
58 } catch (e) { 58 } catch (e) {
59 Log.w(e.toString()); 59 Log.w(e.toString());
60 throw '年龄格式错误'; 60 throw '年龄格式错误';
@@ -69,8 +69,9 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; { @@ -69,8 +69,9 @@ class UserBloc extends Bloc&lt;UserEvent, UserState&gt; {
69 break; 69 break;
70 case ModifyUserInformationType.gender: 70 case ModifyUserInformationType.gender:
71 try { 71 try {
72 - await UserDao.updateUserInfoField(gender: tempGender);  
73 - user.gender = tempGender; 72 + var gender = int.parse(event.content);
  73 + await UserDao.updateUserInfoField(gender: gender);
  74 + user.gender = gender;
74 emitter(UserInfoUpdated()); 75 emitter(UserInfoUpdated());
75 } catch (e) { 76 } catch (e) {
76 Log.e('_updateUser gender, e: $e'); 77 Log.e('_updateUser gender, e: $e');
lib/pages/user/bloc/user_event.dart
@@ -12,8 +12,9 @@ class UserDelete extends UserEvent {} @@ -12,8 +12,9 @@ class UserDelete extends UserEvent {}
12 12
13 class UserUpdate extends UserEvent { 13 class UserUpdate extends UserEvent {
14 final ModifyUserInformationType type; 14 final ModifyUserInformationType type;
  15 + final String content;
15 16
16 - UserUpdate(this.type); 17 + UserUpdate(this.type,this.content);
17 } 18 }
18 19
19 class UserUIUpdate extends UserEvent { 20 class UserUIUpdate extends UserEvent {
lib/pages/user/information/user_information_page.dart
@@ -6,6 +6,7 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;; @@ -6,6 +6,7 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;;
6 import 'package:wow_english/common/widgets/we_app_bar.dart'; 6 import 'package:wow_english/common/widgets/we_app_bar.dart';
7 import 'package:wow_english/models/user_entity.dart'; 7 import 'package:wow_english/models/user_entity.dart';
8 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 8 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
  9 +import 'package:wow_english/route/route.dart';
9 import 'package:wow_english/utils/image_util.dart'; 10 import 'package:wow_english/utils/image_util.dart';
10 import 'package:wow_english/utils/log_util.dart'; 11 import 'package:wow_english/utils/log_util.dart';
11 12
@@ -16,35 +17,19 @@ class UserInformationPage extends StatelessWidget { @@ -16,35 +17,19 @@ class UserInformationPage extends StatelessWidget {
16 17
17 @override 18 @override
18 Widget build(BuildContext context) { 19 Widget build(BuildContext context) {
19 - return BlocProvider(  
20 - create: (context) => UserBloc(),  
21 - child: const _UserInformationView(),  
22 - ); 20 + return BlocBuilder<UserBloc, UserState>(
  21 + builder: (context,state){
  22 + return _UserInformationContentView();
  23 + });
23 } 24 }
24 } 25 }
25 26
26 -class _UserInformationView extends StatelessWidget {  
27 - const _UserInformationView({super.key});  
28 -  
29 - @override  
30 - Widget build(BuildContext context) {  
31 - return BlocListener<UserBloc, UserState>(  
32 - listener: (context, state) {  
33 - Log.d('UserInformationPage: $state');  
34 - },  
35 - child: BlocBuilder<UserBloc, UserState>(builder: (context, state) {  
36 - return _UserInformationContentView();  
37 - }),  
38 - );  
39 - }  
40 -}  
41 27
42 class _UserInformationContentView extends StatelessWidget { 28 class _UserInformationContentView extends StatelessWidget {
43 29
44 void _openModifyPage(BuildContext context, ModifyUserInformationType type) { 30 void _openModifyPage(BuildContext context, ModifyUserInformationType type) {
45 Log.d('_openModifyPage($type)'); 31 Log.d('_openModifyPage($type)');
46 - // 暂时关闭修改,修复后打开  
47 - // ModifyUserInformationPage.push(context, type); 32 + ModifyUserInformationPage.push(context, type);
48 } 33 }
49 34
50 @override 35 @override
@@ -68,7 +53,9 @@ class _UserInformationContentView extends StatelessWidget { @@ -68,7 +53,9 @@ class _UserInformationContentView extends StatelessWidget {
68 radius: 21.r, 53 radius: 21.r,
69 backgroundImage: ImageUtil.getImageProviderOnDefault(user.avatarUrl), 54 backgroundImage: ImageUtil.getImageProviderOnDefault(user.avatarUrl),
70 ), 55 ),
71 - )), 56 + ),
  57 + onTap: () => pushNamed(AppRouteName.userAvatar)
  58 + ),
72 11.verticalSpace, 59 11.verticalSpace,
73 _buildContentRow( 60 _buildContentRow(
74 '名字', 61 '名字',
@@ -144,9 +131,9 @@ class _UserInformationContentView extends StatelessWidget { @@ -144,9 +131,9 @@ class _UserInformationContentView extends StatelessWidget {
144 32.horizontalSpace, 131 32.horizontalSpace,
145 Expanded( 132 Expanded(
146 child: Container( 133 child: Container(
147 - alignment: Alignment.centerLeft,  
148 - child: contentWidget,  
149 - )), 134 + alignment: Alignment.centerLeft,
  135 + child: contentWidget,
  136 + )),
150 Offstage( 137 Offstage(
151 offstage: isHideEndIcon, 138 offstage: isHideEndIcon,
152 child: Image.asset(AssetsConst.icNext, width: 20.w, height: 25.h), 139 child: Image.asset(AssetsConst.icNext, width: 20.w, height: 25.h),
lib/pages/user/modify/modify_user_avatar_page.dart
  1 +import 'dart:io';
  2 +
  3 +import 'package:flutter/material.dart';
  4 +import 'package:flutter_bloc/flutter_bloc.dart';
  5 +import 'package:flutter_screenutil/flutter_screenutil.dart';
  6 +import 'package:wow_english/common/extension/string_extension.dart';
  7 +import 'package:wow_english/common/widgets/ow_image_widget.dart';
  8 +import 'package:wow_english/common/widgets/we_app_bar.dart';
  9 +import 'package:wow_english/pages/user/bloc/user_bloc.dart';
  10 +import 'package:wow_english/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart';
  11 +import 'package:wow_english/utils/toast_util.dart';
  12 +
  13 +class ModifyUserAvatarPage extends StatelessWidget {
  14 + const ModifyUserAvatarPage({super.key, required this.pageType});
  15 +
  16 + /// 0 新用户设置头像 1 修改头像
  17 + final int pageType;
  18 +
  19 + @override
  20 + Widget build(BuildContext context) {
  21 + return BlocProvider(
  22 + create: (context) => UserAvatarBloc(),
  23 + child: _ModifyUserAvatarPage(pageType: pageType),
  24 + );
  25 + }
  26 +}
  27 +
  28 +class _ModifyUserAvatarPage extends StatelessWidget {
  29 + const _ModifyUserAvatarPage({required this.pageType});
  30 + final int pageType;
  31 +
  32 + @override
  33 + Widget build(BuildContext context) {
  34 + return MultiBlocListener(
  35 + listeners: [
  36 + BlocListener<UserBloc,UserState>(
  37 + listener: (context, state){
  38 + if (state is UserInfoUpdated) {
  39 + showToast('修改成功');
  40 + }
  41 + }),
  42 + BlocListener(
  43 + listener: (context,state){
  44 + if (state is ChangeImageState) {
  45 + showToast('上传图片');
  46 + }
  47 + },)
  48 + ],
  49 + child: pageType == 0 ? _setUserAvatarView():_modifyUserAvatarPageView(),
  50 + );
  51 + }
  52 +
  53 + ///个人信息修改头像
  54 + Widget _modifyUserAvatarPageView() => BlocBuilder<UserAvatarBloc,UserAvatarState>(
  55 + builder: (context,state){
  56 + return Scaffold(
  57 + appBar:const WEAppBar(
  58 + titleText: '头像修改',
  59 + ),
  60 + body: SafeArea(
  61 + child: Column(
  62 + children: [
  63 + 20.verticalSpace,
  64 + _avatarImageWidget(),
  65 + ],
  66 + ),
  67 + ),
  68 + );
  69 + });
  70 +
  71 + ///新用户设置头像
  72 + Widget _setUserAvatarView() => BlocBuilder<UserAvatarBloc,UserAvatarState>(
  73 + builder: (context, state) {
  74 + final bloc = BlocProvider.of<UserAvatarBloc>(context);
  75 + return Container(
  76 + color: Colors.white,
  77 + child: SafeArea(
  78 + child: Column(
  79 + children: [
  80 + 20.verticalSpace,
  81 + Row(
  82 + children: [
  83 + Image.asset(
  84 + 'wow_logo'.assetPng,
  85 + height: 49.h,
  86 + width: 84.w,
  87 + ),
  88 + Text(
  89 + '欢迎登录wow english\n接下来请填写一下您的个人信息吧',
  90 + textAlign: TextAlign.left,
  91 + style: TextStyle(
  92 + fontSize: 17.sp,
  93 + color: const Color(0xFF666666)
  94 + ),
  95 + )
  96 + ],
  97 + ),
  98 + 15.verticalSpace,
  99 + _avatarImageWidget(),
  100 + 10.verticalSpace,
  101 + Container(
  102 + width: 176.w,
  103 + height: 52.h,
  104 + padding: const EdgeInsets.all(5),
  105 + decoration: BoxDecoration(
  106 + image: DecorationImage(
  107 + image: AssetImage(bloc.canInsertApp?'oninto'.assetPng:'intowow'.assetPng),
  108 + fit: BoxFit.fill
  109 + )
  110 + ),
  111 + alignment: Alignment.center,
  112 + child: Text(
  113 + '进入wow english',
  114 + textAlign: TextAlign.center,
  115 + style: TextStyle(
  116 + fontSize: 12.sp,
  117 + color: Colors.white
  118 + ),
  119 + ),
  120 + )
  121 + ],
  122 + ),
  123 + ),
  124 + );
  125 + }
  126 + );
  127 +
  128 + Widget _avatarImageWidget() => BlocBuilder<UserAvatarBloc,UserAvatarState>(
  129 + builder: (context, state){
  130 + final bloc = BlocProvider.of<UserAvatarBloc>(context);
  131 + return Row(
  132 + mainAxisAlignment: MainAxisAlignment.center,
  133 + children: [
  134 + Container(
  135 + width: 205.w,
  136 + height: 197.h,
  137 + padding: const EdgeInsets.all(5),
  138 + decoration: BoxDecoration(
  139 + image: DecorationImage(
  140 + image: AssetImage('video_background'.assetPng),
  141 + fit: BoxFit.fill
  142 + )
  143 + ),
  144 + child: bloc.file == null ?
  145 + OwImageWidget(name: bloc.imageUrl):
  146 + Image.file(
  147 + File(bloc.file!.path),
  148 + fit: BoxFit.fill,
  149 + ),
  150 + ),
  151 + 54.horizontalSpace,
  152 + Column(
  153 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  154 + children: [
  155 + GestureDetector(
  156 + onTap: () => bloc.add(GetImageFromCameraEvent()),
  157 + child: Container(
  158 + width: 222.w,
  159 + height: 65.h,
  160 + alignment: Alignment.center,
  161 + decoration: BoxDecoration(
  162 + image: DecorationImage(
  163 + image: AssetImage('alter'.assetPng),
  164 + fit: BoxFit.fill
  165 + )
  166 + ),
  167 + child: Text(
  168 + '拍照修改头像',
  169 + textAlign: TextAlign.center,
  170 + style: TextStyle(
  171 + color: Colors.white,
  172 + fontSize: 20.sp
  173 + ),
  174 + ),
  175 + ),
  176 + ),
  177 + 20.verticalSpace,
  178 + GestureDetector(
  179 + onTap: () => bloc.add(GetImageFromPhotoEvent()),
  180 + child: Container(
  181 + width: 222.w,
  182 + height: 65.h,
  183 + alignment: Alignment.center,
  184 + decoration: BoxDecoration(
  185 + image: DecorationImage(
  186 + image: AssetImage('alter'.assetPng),
  187 + fit: BoxFit.fill
  188 + )
  189 + ),
  190 + child: Text(
  191 + '从相册选择',
  192 + textAlign: TextAlign.center,
  193 + style: TextStyle(
  194 + color: Colors.white,
  195 + fontSize: 20.sp
  196 + ),
  197 + ),
  198 + ),
  199 + )
  200 + ],
  201 + )
  202 + ],
  203 + );
  204 + });
  205 +}
0 \ No newline at end of file 206 \ No newline at end of file
lib/pages/user/modify/modify_user_information_page.dart
@@ -8,7 +8,9 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;; @@ -8,7 +8,9 @@ import &#39;package:wow_english/common/core/user_util.dart&#39;;
8 import 'package:wow_english/common/widgets/textfield_customer_widget.dart'; 8 import 'package:wow_english/common/widgets/textfield_customer_widget.dart';
9 import 'package:wow_english/common/widgets/we_app_bar.dart'; 9 import 'package:wow_english/common/widgets/we_app_bar.dart';
10 import 'package:wow_english/pages/user/bloc/user_bloc.dart'; 10 import 'package:wow_english/pages/user/bloc/user_bloc.dart';
11 -import 'package:wow_english/utils/log_util.dart'; 11 +import 'package:wow_english/pages/user/modify/user_info_bloc/user_info_bloc.dart';
  12 +import 'package:wow_english/route/route.dart';
  13 +import 'package:wow_english/utils/toast_util.dart';
12 14
13 enum ModifyUserInformationType { 15 enum ModifyUserInformationType {
14 avatar('头像'), 16 avatar('头像'),
@@ -34,97 +36,127 @@ class ModifyUserInformationPage extends StatelessWidget { @@ -34,97 +36,127 @@ class ModifyUserInformationPage extends StatelessWidget {
34 36
35 @override 37 @override
36 Widget build(BuildContext context) { 38 Widget build(BuildContext context) {
  39 + String text = '';
  40 + if (type == ModifyUserInformationType.age) {
  41 + text = UserUtil.getUser()!.age.toString();
  42 + } else if (type == ModifyUserInformationType.name) {
  43 + text = UserUtil.getUser()!.name;
  44 + }
37 return BlocProvider( 45 return BlocProvider(
38 - create: (context) => UserBloc(),  
39 - child: Scaffold(  
40 - backgroundColor: Colors.white,  
41 - appBar: WEAppBar(  
42 - titleText: '修改${type.title}',  
43 - ),  
44 - body: BlocListener<UserBloc, UserState>(  
45 - listener: (context, state) {},  
46 - child: BlocBuilder<UserBloc, UserState>(builder: (context, state) {  
47 - //final bloc = context.read<UserBloc>();  
48 - // 区别是什么?  
49 - //BlocProvider.of<UserBloc>(context);  
50 - return SingleChildScrollView(  
51 - child: Column(  
52 - children: [  
53 - Padding(  
54 - padding: EdgeInsets.only(left: 65.w, right: 55.w, top: 38.h),  
55 - child: Row( 46 + create: (context) => UserInfoBloc()..add(InitControllerTextEvent(text)),
  47 + child: MultiBlocListener(
  48 + listeners: [
  49 + BlocListener<UserBloc,UserState>(listener: (context, state){
  50 + if (state is UserInfoUpdated) {
  51 + showToast('修改成功');
  52 + popPage();
  53 + }
  54 + })
  55 + ],
  56 + child: Scaffold(
  57 + backgroundColor: Colors.white,
  58 + appBar: WEAppBar(
  59 + titleText: '修改${type.title}',
  60 + ),
  61 + body: BlocBuilder<UserInfoBloc, UserInfoState>(
  62 + builder: (context, state) {
  63 + final bloc = BlocProvider.of<UserInfoBloc>(context);
  64 + return SingleChildScrollView(
  65 + child: Column(
56 children: [ 66 children: [
57 - Text(  
58 - type.title,  
59 - style: TextStyle(  
60 - fontWeight: FontWeight.w700,  
61 - color: const Color(0xFF333333),  
62 - fontSize: 21.sp,  
63 - ),  
64 - ),  
65 - 20.horizontalSpace,  
66 - // 输入框 or 选择框  
67 - _buildTextFieldWidget(context),  
68 - // 占位  
69 - Expanded(  
70 - child: Container(),  
71 - ),  
72 - // 按钮  
73 - GestureDetector(  
74 - onTap: () {  
75 - // 更新type类型的字段  
76 - context.read<UserBloc>().add(UserUpdate(type));  
77 - },  
78 - child: Container(  
79 - alignment: Alignment.center,  
80 - width: 90.w,  
81 - height: 44.h,  
82 - decoration: const BoxDecoration(  
83 - image: DecorationImage(image: AssetImage(AssetsConst.bgButtonBlue), fit: BoxFit.fill), 67 + Padding(
  68 + padding: EdgeInsets.only(left: 65.w, right: 55.w, top: 38.h),
  69 + child: Row(
  70 + children: [
  71 + Text(
  72 + type.title,
  73 + style: TextStyle(
  74 + fontWeight: FontWeight.w700,
  75 + color: const Color(0xFF333333),
  76 + fontSize: 21.sp,
  77 + ),
  78 + ),
  79 + 20.horizontalSpace,
  80 + // 输入框 or 选择框
  81 + _buildTextFieldWidget(context),
  82 + // 占位
  83 + Expanded(
  84 + child: Container(),
  85 + ),
  86 + // 按钮
  87 + GestureDetector(
  88 + onTap: () {
  89 + var text = '';
  90 + if (type == ModifyUserInformationType.name || type == ModifyUserInformationType.age){
  91 + if(bloc.modifyTextController.text.isEmpty) {
  92 + showToast('内容不能为空');
  93 + return;
  94 + }
  95 + text = bloc.modifyTextController.text;
  96 + }
  97 +
  98 + if (type == ModifyUserInformationType.gender) {
  99 + text = bloc.gender.toString();
  100 + }
  101 + // 更新type类型的字段
  102 + context.read<UserBloc>().add(UserUpdate(type,text));
  103 + },
  104 + child: Container(
  105 + alignment: Alignment.center,
  106 + width: 90.w,
  107 + height: 44.h,
  108 + decoration: const BoxDecoration(
  109 + image: DecorationImage(image: AssetImage(AssetsConst.bgButtonBlue), fit: BoxFit.fill),
  110 + ),
  111 + child: Text(
  112 + '确定',
  113 + style: TextStyle(fontSize: 17.sp, color: Colors.white),
  114 + ),
  115 + ),
  116 + )
  117 + ],
  118 + )),
  119 + Stack(
  120 + alignment: Alignment.topRight,
  121 + children: [
  122 + Image.asset(
  123 + AssetsConst.bgEditUserInformation,
  124 + width: double.infinity,
84 ), 125 ),
85 - child: Text(  
86 - '确定',  
87 - style: TextStyle(fontSize: 17.sp, color: Colors.white), 126 + Positioned(
  127 + right: 125.w,
  128 + top: 10.h,
  129 + child: Image.asset(AssetsConst.bgIcSteveWrite, width: 161.w, height: 249.w),
88 ), 130 ),
89 - ),  
90 - ) 131 + ],
  132 + ),
91 ], 133 ],
92 - )),  
93 - Stack(  
94 - alignment: Alignment.topRight,  
95 - children: [  
96 - Image.asset(  
97 - AssetsConst.bgEditUserInformation,  
98 - width: double.infinity,  
99 - ),  
100 - Positioned(  
101 - right: 125.w,  
102 - top: 10.h,  
103 - child: Image.asset(AssetsConst.bgIcSteveWrite, width: 161.w, height: 249.w),  
104 - ),  
105 - ],  
106 - ),  
107 - ],  
108 - ));  
109 - }), 134 + ));
  135 + }),
110 ), 136 ),
111 ), 137 ),
112 ); 138 );
113 } 139 }
114 140
115 Widget _buildTextFieldWidget(BuildContext context) { 141 Widget _buildTextFieldWidget(BuildContext context) {
116 - var userBloc = context.read<UserBloc>();  
117 - var user = UserUtil.getUser()!;  
118 - userBloc.tempGender = user.gender ?? 0;  
119 - Log.d('user = $user');  
120 if (type == ModifyUserInformationType.gender) { 142 if (type == ModifyUserInformationType.gender) {
121 - return Row(  
122 - children: <Widget>[  
123 - _buildSexWidget('男', true),  
124 - 70.horizontalSpace,  
125 - _buildSexWidget('女', false)  
126 - ],  
127 - ); 143 + return BlocBuilder<UserInfoBloc, UserInfoState>(
  144 + builder: (context,state){
  145 + final bloc = BlocProvider.of<UserInfoBloc>(context);
  146 + return Row(
  147 + children: <Widget>[
  148 + GestureDetector(
  149 + onTap: () => bloc.add(ChangeGenderEvent(0)),
  150 + child: _buildSexWidget('男', bloc.gender == 0),
  151 + ),
  152 + 70.horizontalSpace,
  153 + GestureDetector(
  154 + onTap: () => bloc.add(ChangeGenderEvent(1)),
  155 + child: _buildSexWidget('女', bloc.gender == 1),
  156 + )
  157 + ],
  158 + );
  159 + });
128 } 160 }
129 161
130 var formatters = [ 162 var formatters = [
@@ -141,22 +173,26 @@ class ModifyUserInformationPage extends StatelessWidget { @@ -141,22 +173,26 @@ class ModifyUserInformationPage extends StatelessWidget {
141 inputType = TextInputType.number; 173 inputType = TextInputType.number;
142 } 174 }
143 175
144 - return TextFieldCustomerWidget(  
145 - height: 65.h,  
146 - width: 222.w,  
147 - textStyle: TextStyle(  
148 - fontWeight: FontWeight.w700,  
149 - color: const Color(0xFF333333),  
150 - fontSize: 21.sp,  
151 - ),  
152 - bgImageName: 'Input_layer_up',  
153 - textInputType: inputType,  
154 - inputFormatters: formatters,  
155 - controller: userBloc.modifyTextController,  
156 - /*onChangeValue: (String value) { 176 + return BlocBuilder<UserInfoBloc, UserInfoState>(
  177 + builder: (context,state){
  178 + final bloc = BlocProvider.of<UserInfoBloc>(context);
  179 + return TextFieldCustomerWidget(
  180 + height: 65.h,
  181 + width: 222.w,
  182 + textStyle: TextStyle(
  183 + fontWeight: FontWeight.w700,
  184 + color: const Color(0xFF333333),
  185 + fontSize: 21.sp,
  186 + ),
  187 + bgImageName: 'Input_layer_up',
  188 + textInputType: inputType,
  189 + inputFormatters: formatters,
  190 + controller: bloc.modifyTextController,
  191 + /*onChangeValue: (String value) {
157 bloc.add(CodeNumberChangeEvent()); 192 bloc.add(CodeNumberChangeEvent());
158 },*/ 193 },*/
159 - ); 194 + );
  195 + });
160 } 196 }
161 197
162 Widget _buildSexWidget(String title,bool isSelect) { 198 Widget _buildSexWidget(String title,bool isSelect) {
lib/pages/user/modify/user_avatar_bloc/user_avatar_bloc.dart 0 → 100644
  1 +import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:image_picker/image_picker.dart';
  4 +import 'package:permission_handler/permission_handler.dart';
  5 +import 'package:wow_english/common/core/assets_const.dart';
  6 +import 'package:wow_english/common/core/user_util.dart';
  7 +
  8 +part 'user_avatar_event.dart';
  9 +part 'user_avatar_state.dart';
  10 +
  11 +class UserAvatarBloc extends Bloc<UserAvatarEvent, UserAvatarState> {
  12 +
  13 + String _imageUrl = UserUtil.getUser()!.avatarUrl??AssetsConst.wowLogo;
  14 +
  15 + String get imageUrl => _imageUrl;
  16 +
  17 + XFile? _file;
  18 +
  19 + XFile? get file => _file;
  20 +
  21 + bool _canInsertApp =false;
  22 +
  23 + bool get canInsertApp => _canInsertApp;
  24 +
  25 + final ImagePicker picker = ImagePicker();
  26 +
  27 +
  28 + UserAvatarBloc() : super(UserAvatarInitial()) {
  29 + on<ChangeImageEvent>(_changeImage);
  30 + on<GetImageFromPhotoEvent>(_getImageFromPhoto);
  31 + on<GetImageFromCameraEvent>(_getImageFromCamera);
  32 + }
  33 +
  34 + void _changeImage(ChangeImageEvent event,Emitter<UserAvatarState> emitter) async {
  35 + _imageUrl = event.imagePath;
  36 + emitter(ChangeImageState());
  37 + }
  38 +
  39 + void _getImageFromPhoto(GetImageFromPhotoEvent event,Emitter<UserAvatarState> emitter) async {
  40 + await getPhotoPermissionStatus().then((value) async {
  41 + if (!value){
  42 + debugPrint('失败$value');
  43 + return;
  44 + }
  45 + _file = await picker.pickImage(source: ImageSource.gallery);
  46 + emitter(ChangeImageState());
  47 + });
  48 + }
  49 +
  50 + void _getImageFromCamera(GetImageFromCameraEvent event,Emitter<UserAvatarState> emitter) async {
  51 + await getCameraPermissionStatus().then((value) async {
  52 + if (!value){
  53 + debugPrint('失败$value');
  54 + return;
  55 + }
  56 + _file = await picker.pickImage(source: ImageSource.camera);
  57 + emitter(ChangeImageState());
  58 + });
  59 + }
  60 +
  61 + ///获取相机权限
  62 + Future<bool> getCameraPermissionStatus() async {
  63 + Permission permission = Permission.camera;
  64 + //granted 通过,denied 被拒绝,permanentlyDenied 拒绝且不在提示
  65 + PermissionStatus status = await permission.status;
  66 + if (status.isGranted) {
  67 + return true;
  68 + } else if (status.isDenied) {
  69 + _requestPermission(permission);
  70 + } else if (status.isPermanentlyDenied) {
  71 + openAppSettings();
  72 + } else if (status.isRestricted) {
  73 + _requestPermission(permission);
  74 + } else {
  75 +
  76 + }
  77 + return false;
  78 + }
  79 +
  80 + ///获取相册权限
  81 + Future<bool> getPhotoPermissionStatus() async {
  82 + Permission permission = Permission.photos;
  83 + PermissionStatus status = await permission.status;
  84 + if (status.isGranted) {
  85 + return true;
  86 + } else if (status.isDenied) {
  87 + _requestPermission(permission);
  88 + } else if (status.isPermanentlyDenied) {
  89 + openAppSettings();
  90 + } else if (status.isRestricted) {
  91 + _requestPermission(permission);
  92 + } else {
  93 +
  94 + }
  95 + return false;
  96 + }
  97 +
  98 + /// 获取权限
  99 + void _requestPermission(Permission permission) async {
  100 + PermissionStatus status = await permission.request();
  101 + if (status.isPermanentlyDenied) {
  102 + openAppSettings();
  103 + }
  104 + }
  105 +}
lib/pages/user/modify/user_avatar_bloc/user_avatar_event.dart 0 → 100644
  1 +part of 'user_avatar_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class UserAvatarEvent {}
  5 +
  6 +class GetImageFromPhotoEvent extends UserAvatarEvent {}
  7 +
  8 +class GetImageFromCameraEvent extends UserAvatarEvent {}
  9 +
  10 +class ChangeImageEvent extends UserAvatarEvent {
  11 + final String imagePath;
  12 + ChangeImageEvent(this.imagePath);
  13 +}
lib/pages/user/modify/user_avatar_bloc/user_avatar_state.dart 0 → 100644
  1 +part of 'user_avatar_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class UserAvatarState {}
  5 +
  6 +class UserAvatarInitial extends UserAvatarState {}
  7 +
  8 +class ChangeImageState extends UserAvatarState {}
lib/pages/user/modify/user_info_bloc/user_info_bloc.dart 0 → 100644
  1 +import 'package:flutter/cupertino.dart';
  2 +import 'package:flutter_bloc/flutter_bloc.dart';
  3 +import 'package:wow_english/common/core/user_util.dart';
  4 +
  5 +part 'user_info_event.dart';
  6 +part 'user_info_state.dart';
  7 +
  8 +class UserInfoBloc extends Bloc<UserInfoEvent, UserInfoState> {
  9 + final TextEditingController modifyTextController = TextEditingController();
  10 +
  11 + int _gender = UserUtil.getUser()!.gender??0;
  12 +
  13 + int get gender => _gender;
  14 +
  15 + UserInfoBloc() : super(UserInfoInitial()) {
  16 + on<ChangeGenderEvent>(_changeGender);
  17 + on<InitControllerTextEvent>(_initControllerText);
  18 + }
  19 +
  20 + _initControllerText(InitControllerTextEvent event,Emitter<UserInfoState> emitter) async {
  21 + modifyTextController.text = event.text;
  22 + }
  23 +
  24 + _changeGender(ChangeGenderEvent event,Emitter<UserInfoState> emitter) async {
  25 + _gender = event.gender;
  26 + emitter(ChangeGenderState());
  27 + }
  28 +}
lib/pages/user/modify/user_info_bloc/user_info_event.dart 0 → 100644
  1 +part of 'user_info_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class UserInfoEvent {}
  5 +
  6 +class InitControllerTextEvent extends UserInfoEvent {
  7 + final String text;
  8 + InitControllerTextEvent(this.text);
  9 +}
  10 +
  11 +class ChangeGenderEvent extends UserInfoEvent {
  12 + final int gender;
  13 + ChangeGenderEvent(this.gender);
  14 +}
lib/pages/user/modify/user_info_bloc/user_info_state.dart 0 → 100644
  1 +part of 'user_info_bloc.dart';
  2 +
  3 +@immutable
  4 +abstract class UserInfoState {}
  5 +
  6 +class UserInfoInitial extends UserInfoState {}
  7 +
  8 +class ChangeGenderState extends UserInfoState {}
lib/pages/user/user_page.dart
@@ -16,10 +16,7 @@ class UserPage extends StatelessWidget { @@ -16,10 +16,7 @@ class UserPage extends StatelessWidget {
16 16
17 @override 17 @override
18 Widget build(BuildContext context) { 18 Widget build(BuildContext context) {
19 - return BlocProvider(  
20 - create: (context) => UserBloc(),  
21 - child: _UserView(),  
22 - ); 19 + return _UserView();
23 } 20 }
24 } 21 }
25 22
@@ -32,38 +29,37 @@ class _UserView extends StatelessWidget { @@ -32,38 +29,37 @@ class _UserView extends StatelessWidget {
32 } 29 }
33 30
34 Widget _pageWidget() => BlocBuilder<UserBloc, UserState>( 31 Widget _pageWidget() => BlocBuilder<UserBloc, UserState>(
35 - /*buildWhen: (previous, current) { 32 + /*buildWhen: (previous, current) {
36 return current != previous; 33 return current != previous;
37 },*/ 34 },*/
38 - builder: (context, state) {  
39 - UserEntity user = UserUtil.getUser()!;  
40 - final userBloc = BlocProvider.of<UserBloc>(context); 35 + builder: (context, state) {
  36 + UserEntity user = UserUtil.getUser()!;
  37 + final userBloc = BlocProvider.of<UserBloc>(context);
41 38
42 - // 常规按钮的字体样式  
43 - final textStyle21sp = TextStyle(  
44 - //fontWeight: FontWeight.w600,  
45 - color: const Color(0xFF333333),  
46 - fontSize: 21.sp,  
47 - ); 39 + // 常规按钮的字体样式
  40 + final textStyle21sp = TextStyle(
  41 + //fontWeight: FontWeight.w600,
  42 + color: const Color(0xFF333333),
  43 + fontSize: 21.sp,
  44 + );
48 45
49 - // 常规按钮的样式  
50 - var normalButtonStyle = ButtonStyle(  
51 - side: MaterialStateProperty.all(BorderSide(color: const Color(0xFF140C10), width: 1.5.w)),  
52 - shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),  
53 - minimumSize: MaterialStateProperty.all(Size(double.infinity, 58.h)),  
54 - backgroundColor: MaterialStateProperty.all(Colors.white),  
55 - ); 46 + // 常规按钮的样式
  47 + var normalButtonStyle = ButtonStyle(
  48 + side: MaterialStateProperty.all(BorderSide(color: const Color(0xFF140C10), width: 1.5.w)),
  49 + shape: MaterialStateProperty.all(RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),
  50 + minimumSize: MaterialStateProperty.all(Size(double.infinity, 58.h)),
  51 + backgroundColor: MaterialStateProperty.all(Colors.white),
  52 + );
56 53
57 - return Scaffold(  
58 - //backgroundColor: Colors.white,  
59 - appBar: const WEAppBar(),  
60 - body: SingleChildScrollView(  
61 - padding: EdgeInsets.only(left: 17.w, right: 17.w, top: 10.h, bottom: 22.h),  
62 - child: Column(  
63 - mainAxisAlignment: MainAxisAlignment.center,  
64 - children: <Widget>[  
65 - // todo banner,暂时没有接口获取banner URL  
66 - /*Offstage( 54 + return Scaffold(
  55 + appBar: const WEAppBar(),
  56 + body: SingleChildScrollView(
  57 + padding: EdgeInsets.only(left: 17.w, right: 17.w, top: 10.h, bottom: 22.h),
  58 + child: Column(
  59 + mainAxisAlignment: MainAxisAlignment.center,
  60 + children: <Widget>[
  61 + // todo banner,暂时没有接口获取banner URL
  62 + /*Offstage(
67 child: Column( 63 child: Column(
68 children: [ 64 children: [
69 Container(child: Image.asset(bannerUrl), constraints: BoxConstraints(maxHeight: 196.h)), 65 Container(child: Image.asset(bannerUrl), constraints: BoxConstraints(maxHeight: 196.h)),
@@ -71,23 +67,23 @@ class _UserView extends StatelessWidget { @@ -71,23 +67,23 @@ class _UserView extends StatelessWidget {
71 ], 67 ],
72 ), 68 ),
73 ),*/ 69 ),*/
74 - Row(  
75 - mainAxisAlignment: MainAxisAlignment.spaceBetween,  
76 - children: [  
77 - CircleAvatar(  
78 - radius: 40.r,  
79 - backgroundColor: const Color(0xFF140C10),  
80 - child: CircleAvatar(  
81 - radius: 38.5.r,  
82 - backgroundImage: ImageUtil.getImageProviderOnDefault(user.avatarUrl),  
83 - ),  
84 - /*child: ClipOval( 70 + Row(
  71 + mainAxisAlignment: MainAxisAlignment.spaceBetween,
  72 + children: [
  73 + CircleAvatar(
  74 + radius: 40.r,
  75 + backgroundColor: const Color(0xFF140C10),
  76 + child: CircleAvatar(
  77 + radius: 38.5.r,
  78 + backgroundImage: ImageUtil.getImageProviderOnDefault(user.avatarUrl),
  79 + ),
  80 + /*child: ClipOval(
85 child: OwImageWidget(name: user.avatarUrl ?? AssetsConst.wowLogo, fit: BoxFit.contain,), 81 child: OwImageWidget(name: user.avatarUrl ?? AssetsConst.wowLogo, fit: BoxFit.contain,),
86 )*/ 82 )*/
87 - ),  
88 - 32.horizontalSpace,  
89 - Expanded(  
90 - child: Column( 83 + ),
  84 + 32.horizontalSpace,
  85 + Expanded(
  86 + child: Column(
91 children: [ 87 children: [
92 Row( 88 Row(
93 children: [ 89 children: [
@@ -131,94 +127,94 @@ class _UserView extends StatelessWidget { @@ -131,94 +127,94 @@ class _UserView extends StatelessWidget {
131 ) 127 )
132 ], 128 ],
133 )), 129 )),
134 - Offstage(  
135 - offstage: UserUtil.getUser()?.phoneNum == '17730280759',  
136 - child: TextButton(  
137 - child: Text(  
138 - "修改个人信息>",  
139 - style: textStyle21sp,  
140 - ),  
141 - onPressed: () {  
142 - pushNamed(AppRouteName.userInformation);  
143 - },  
144 - ),  
145 - )  
146 - ],  
147 - ),  
148 - 30.verticalSpace,  
149 - OutlinedButton(  
150 - onPressed: () => pushNamed(AppRouteName.fogPwd),  
151 - style: normalButtonStyle,  
152 - child: Text(  
153 - "修改密码",  
154 - style: textStyle21sp,  
155 - ),  
156 - ),  
157 - 12.verticalSpace,  
158 - // todo 为了过审,把测试账号兑换功能下掉  
159 - Offstage(  
160 - offstage: UserUtil.getUser()?.phoneNum == '17730280759',  
161 - child: OutlinedButton(  
162 - onPressed: () => pushNamed(AppRouteName.exLesson),  
163 - style: normalButtonStyle,  
164 - child: Text(  
165 - "兑换课程",  
166 - style: textStyle21sp,  
167 - )),  
168 - ),  
169 Offstage( 130 Offstage(
170 offstage: UserUtil.getUser()?.phoneNum == '17730280759', 131 offstage: UserUtil.getUser()?.phoneNum == '17730280759',
171 - child: 12.verticalSpace,  
172 - ),  
173 - OutlinedButton(  
174 - onPressed: () {  
175 - pushNamed(AppRouteName.webView,arguments: {'urlStr': AppConsts.userPrivacyPolicyUrl, 'webViewTitle': '隐私协议'});  
176 - },  
177 - style: normalButtonStyle, 132 + child: TextButton(
178 child: Text( 133 child: Text(
179 - "隐私协议", 134 + "修改个人信息>",
180 style: textStyle21sp, 135 style: textStyle21sp,
181 - )),  
182 - 30.verticalSpace,  
183 - OutlinedButton(  
184 - onPressed: () => userBloc.add(UserLogout()),  
185 - style: ButtonStyle(  
186 - side: MaterialStateProperty.all(const BorderSide(color: Color(0xFF140C10), width: 1.5)),  
187 - shape: MaterialStateProperty.all(  
188 - RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),  
189 - minimumSize: MaterialStateProperty.all(Size(295.w, 40.h)),  
190 - backgroundColor: MaterialStateProperty.all(Color(0xFFFBB621)),  
191 ), 136 ),
192 - child: Text(  
193 - "退出登录",  
194 - style: TextStyle(  
195 - //fontWeight: FontWeight.w600,  
196 - color: Colors.white,  
197 - fontSize: 17.sp,  
198 - ),  
199 - )),  
200 - 30.verticalSpace,  
201 - TextButton(  
202 onPressed: () { 137 onPressed: () {
203 - //userBloc.add(UserDelete())  
204 - showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () {  
205 - popPage();  
206 - }, () {  
207 - userBloc.add(UserDelete());  
208 - popPage();  
209 - }); 138 + pushNamed(AppRouteName.userInformation);
210 }, 139 },
211 - child: Text(  
212 - "注销账号",  
213 - style: TextStyle(  
214 - //fontWeight: FontWeight.w600,  
215 - color: Colors.red,  
216 - fontSize: 15.sp,  
217 - ),  
218 - )), 140 + ),
  141 + )
219 ], 142 ],
220 ), 143 ),
221 - ));  
222 - },  
223 - ); 144 + 30.verticalSpace,
  145 + OutlinedButton(
  146 + onPressed: () => pushNamed(AppRouteName.fogPwd),
  147 + style: normalButtonStyle,
  148 + child: Text(
  149 + "修改密码",
  150 + style: textStyle21sp,
  151 + ),
  152 + ),
  153 + 12.verticalSpace,
  154 + // todo 为了过审,把测试账号兑换功能下掉
  155 + Offstage(
  156 + offstage: UserUtil.getUser()?.phoneNum == '17730280759',
  157 + child: OutlinedButton(
  158 + onPressed: () => pushNamed(AppRouteName.exLesson),
  159 + style: normalButtonStyle,
  160 + child: Text(
  161 + "兑换课程",
  162 + style: textStyle21sp,
  163 + )),
  164 + ),
  165 + Offstage(
  166 + offstage: UserUtil.getUser()?.phoneNum == '17730280759',
  167 + child: 12.verticalSpace,
  168 + ),
  169 + OutlinedButton(
  170 + onPressed: () {
  171 + pushNamed(AppRouteName.webView,arguments: {'urlStr': AppConsts.userPrivacyPolicyUrl, 'webViewTitle': '隐私协议'});
  172 + },
  173 + style: normalButtonStyle,
  174 + child: Text(
  175 + "隐私协议",
  176 + style: textStyle21sp,
  177 + )),
  178 + 30.verticalSpace,
  179 + OutlinedButton(
  180 + onPressed: () => userBloc.add(UserLogout()),
  181 + style: ButtonStyle(
  182 + side: MaterialStateProperty.all(const BorderSide(color: Color(0xFF140C10), width: 1.5)),
  183 + shape: MaterialStateProperty.all(
  184 + RoundedRectangleBorder(borderRadius: BorderRadius.circular(15.r))),
  185 + minimumSize: MaterialStateProperty.all(Size(295.w, 40.h)),
  186 + backgroundColor: MaterialStateProperty.all(Color(0xFFFBB621)),
  187 + ),
  188 + child: Text(
  189 + "退出登录",
  190 + style: TextStyle(
  191 + //fontWeight: FontWeight.w600,
  192 + color: Colors.white,
  193 + fontSize: 17.sp,
  194 + ),
  195 + )),
  196 + 30.verticalSpace,
  197 + TextButton(
  198 + onPressed: () {
  199 + //userBloc.add(UserDelete())
  200 + showTwoActionDialog('注销账号', '取消', '注销', '请谨慎操作!\n注销后不可恢复哦!', () {
  201 + popPage();
  202 + }, () {
  203 + userBloc.add(UserDelete());
  204 + popPage();
  205 + });
  206 + },
  207 + child: Text(
  208 + "注销账号",
  209 + style: TextStyle(
  210 + //fontWeight: FontWeight.w600,
  211 + color: Colors.red,
  212 + fontSize: 15.sp,
  213 + ),
  214 + )),
  215 + ],
  216 + ),
  217 + ));
  218 + },
  219 + );
224 } 220 }
lib/route/route.dart
@@ -16,6 +16,7 @@ import &#39;package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.da @@ -16,6 +16,7 @@ import &#39;package:wow_english/pages/shop/exchangelist/exchange_lesson_list_page.da
16 import 'package:wow_english/pages/shop/home/shop_home_page.dart'; 16 import 'package:wow_english/pages/shop/home/shop_home_page.dart';
17 import 'package:wow_english/pages/tab/tab_page.dart'; 17 import 'package:wow_english/pages/tab/tab_page.dart';
18 import 'package:wow_english/pages/user/information/user_information_page.dart'; 18 import 'package:wow_english/pages/user/information/user_information_page.dart';
  19 +import 'package:wow_english/pages/user/modify/modify_user_avatar_page.dart';
19 import 'package:wow_english/pages/user/modify/modify_user_information_page.dart'; 20 import 'package:wow_english/pages/user/modify/modify_user_information_page.dart';
20 import 'package:wow_english/pages/user/user_page.dart'; 21 import 'package:wow_english/pages/user/user_page.dart';
21 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart'; 22 import 'package:wow_english/pages/video/lookvideo/look_video_page.dart';
@@ -42,6 +43,8 @@ class AppRouteName { @@ -42,6 +43,8 @@ class AppRouteName {
42 43
43 /// 用户详细信息页 44 /// 用户详细信息页
44 static const String userInformation = 'userInformation'; 45 static const String userInformation = 'userInformation';
  46 + /// 修改用户头像
  47 + static const String userAvatar = 'userAvatar';
45 48
46 /// 用户修改信息页,不要自己调用,使用[ModifyUserInformationPage.push]方法,隐藏这种实现 49 /// 用户修改信息页,不要自己调用,使用[ModifyUserInformationPage.push]方法,隐藏这种实现
47 //static const String userModifyInformation = 'userModifyInformation'; 50 //static const String userModifyInformation = 'userModifyInformation';
@@ -99,6 +102,13 @@ class AppRouter { @@ -99,6 +102,13 @@ class AppRouter {
99 return CupertinoPageRoute(builder: (_) => const UserPage()); 102 return CupertinoPageRoute(builder: (_) => const UserPage());
100 case AppRouteName.userInformation: 103 case AppRouteName.userInformation:
101 return CupertinoPageRoute(builder: (_) => const UserInformationPage()); 104 return CupertinoPageRoute(builder: (_) => const UserInformationPage());
  105 + case AppRouteName.userAvatar:
  106 + var pageType = 0;
  107 + if (settings.arguments != null) {
  108 + final content = (settings.arguments as Map)['pageType'] as String??'0';
  109 + pageType = int.parse(content);
  110 + }
  111 + return CupertinoPageRoute(builder: (_) => ModifyUserAvatarPage(pageType: pageType,));
102 /*case AppRouteName.userModifyInformation: 112 /*case AppRouteName.userModifyInformation:
103 return CupertinoPageRoute(builder: (_) { 113 return CupertinoPageRoute(builder: (_) {
104 ModifyUserInformationType argument = ModifyUserInformationType.name; 114 ModifyUserInformationType argument = ModifyUserInformationType.name;
pubspec.yaml
@@ -80,7 +80,7 @@ dependencies: @@ -80,7 +80,7 @@ dependencies:
80 # 获取设备信息 https://pub.flutter-io.cn/packages/device_info_plus 80 # 获取设备信息 https://pub.flutter-io.cn/packages/device_info_plus
81 device_info_plus: ^9.0.1 81 device_info_plus: ^9.0.1
82 # 用户权限申请 https://pub.dev/packages/permission_handler 82 # 用户权限申请 https://pub.dev/packages/permission_handler
83 - permission_handler: ^10.2.0 83 + permission_handler: ^10.4.1
84 # 网络状态监听 https://pub.dev/packages/connectivity_plus 84 # 网络状态监听 https://pub.dev/packages/connectivity_plus
85 connectivity_plus: ^4.0.1 85 connectivity_plus: ^4.0.1
86 # iOS设备方向控制 https://pub.dev/packages/limiting_direction_csx 86 # iOS设备方向控制 https://pub.dev/packages/limiting_direction_csx