这是CaiYouHui前端,一个关于flutter的安卓app,前端使用flutter实现

profile_screen.dart 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  1. import 'package:flutter/material.dart';
  2. import 'package:provider/provider.dart';
  3. import '../../providers/auth_provider.dart';
  4. import '../../providers/user_provider.dart';
  5. import '../../navigation/bottom_nav_bar.dart';
  6. import 'profile_detail_screen.dart';
  7. import '../../widgets/custom/protected_widget.dart';
  8. class ProfileScreen extends StatelessWidget {
  9. const ProfileScreen({super.key});
  10. @override
  11. Widget build(BuildContext context) {
  12. return ProtectedWidget(
  13. child: _ProfileContent(),
  14. loadingWidget: const Center(
  15. child: CircularProgressIndicator(),
  16. ),
  17. );
  18. }
  19. }
  20. class _ProfileContent extends StatefulWidget {
  21. @override
  22. State<_ProfileContent> createState() => _ProfileContentState();
  23. }
  24. class _ProfileContentState extends State<_ProfileContent> {
  25. @override
  26. void initState() {
  27. super.initState();
  28. WidgetsBinding.instance.addPostFrameCallback((_) {
  29. final userProvider = Provider.of<UserProvider>(context, listen: false);
  30. userProvider.loadUserProfile();
  31. });
  32. }
  33. @override
  34. Widget build(BuildContext context) {
  35. final authProvider = Provider.of<AuthProvider>(context);
  36. // final userProvider = Provider.of<UserProvider>(context);
  37. return Scaffold(
  38. appBar: AppBar(
  39. title: const Text('我的'),
  40. actions: [
  41. IconButton(
  42. icon: const Icon(Icons.settings_outlined),
  43. onPressed: () {
  44. // 跳转到设置页面
  45. },
  46. ),
  47. ],
  48. ),
  49. body: SingleChildScrollView(
  50. child: Column(
  51. children: [
  52. // 用户信息卡片
  53. Card(
  54. margin: const EdgeInsets.all(16),
  55. shape: RoundedRectangleBorder(
  56. borderRadius: BorderRadius.circular(16),
  57. ),
  58. elevation: 2,
  59. child: Padding(
  60. padding: const EdgeInsets.all(20),
  61. child: Column(
  62. children: [
  63. GestureDetector(
  64. onTap: () {
  65. // 点击头像
  66. },
  67. child: Stack(
  68. children: [
  69. CircleAvatar(
  70. radius: 50,
  71. backgroundColor: Colors.blue[100],
  72. backgroundImage: authProvider.user?.avatar != null
  73. ? NetworkImage(authProvider.user!.avatar!)
  74. : null,
  75. child: authProvider.user?.avatar == null
  76. ? const Icon(
  77. Icons.person,
  78. size: 60,
  79. color: Colors.blue,
  80. )
  81. : null,
  82. ),
  83. Positioned(
  84. bottom: 0,
  85. right: 0,
  86. child: Container(
  87. padding: const EdgeInsets.all(6),
  88. decoration: BoxDecoration(
  89. color: Colors.blue,
  90. borderRadius: BorderRadius.circular(20),
  91. border: Border.all(
  92. color: Colors.white,
  93. width: 2,
  94. ),
  95. ),
  96. child: const Icon(
  97. Icons.edit,
  98. size: 16,
  99. color: Colors.white,
  100. ),
  101. ),
  102. ),
  103. ],
  104. ),
  105. ),
  106. const SizedBox(height: 16),
  107. Text(
  108. authProvider.user?.fullName ?? '用户',
  109. style: const TextStyle(
  110. fontSize: 22,
  111. fontWeight: FontWeight.bold,
  112. ),
  113. ),
  114. const SizedBox(height: 8),
  115. Text(
  116. authProvider.user?.email ?? '',
  117. style: TextStyle(
  118. fontSize: 14,
  119. color: Colors.grey[600],
  120. ),
  121. ),
  122. if (authProvider.user?.phone != null)
  123. Padding(
  124. padding: const EdgeInsets.only(top: 4),
  125. child: Text(
  126. authProvider.user!.phone!,
  127. style: TextStyle(
  128. fontSize: 14,
  129. color: Colors.grey[600],
  130. ),
  131. ),
  132. ),
  133. const SizedBox(height: 16),
  134. Row(
  135. mainAxisAlignment: MainAxisAlignment.center,
  136. children: [
  137. _buildStatItem('关注', '128'),
  138. _buildVerticalDivider(),
  139. _buildStatItem('粉丝', '256'),
  140. _buildVerticalDivider(),
  141. _buildStatItem('积分', '1024'),
  142. ],
  143. ),
  144. ],
  145. ),
  146. ),
  147. ),
  148. // 菜单项
  149. Padding(
  150. padding: const EdgeInsets.symmetric(horizontal: 16),
  151. child: Column(
  152. children: [
  153. _buildMenuCard(
  154. title: '账户设置',
  155. items: [
  156. _buildMenuItem(
  157. icon: Icons.person_outline,
  158. title: '个人信息',
  159. subtitle: '查看和编辑个人信息',
  160. onTap: () {
  161. Navigator.of(context).push(
  162. MaterialPageRoute(
  163. builder: (_) => const ProfileDetailScreen(),
  164. ),
  165. );
  166. },
  167. ),
  168. _buildMenuItem(
  169. icon: Icons.lock_outline,
  170. title: '账号安全',
  171. subtitle: '修改密码和安全设置',
  172. onTap: () {},
  173. ),
  174. _buildMenuItem(
  175. icon: Icons.notifications_none,
  176. title: '消息通知',
  177. subtitle: '管理通知偏好设置',
  178. onTap: () {},
  179. ),
  180. ],
  181. ),
  182. const SizedBox(height: 16),
  183. _buildMenuCard(
  184. title: '我的内容',
  185. items: [
  186. _buildMenuItem(
  187. icon: Icons.bookmark_border,
  188. title: '我的收藏',
  189. subtitle: '查看收藏的内容',
  190. onTap: () {},
  191. ),
  192. _buildMenuItem(
  193. icon: Icons.history,
  194. title: '浏览历史',
  195. subtitle: '查看最近浏览记录',
  196. onTap: () {},
  197. ),
  198. _buildMenuItem(
  199. icon: Icons.download,
  200. title: '我的下载',
  201. subtitle: '管理下载的文件',
  202. onTap: () {},
  203. ),
  204. ],
  205. ),
  206. const SizedBox(height: 16),
  207. _buildMenuCard(
  208. title: '其他',
  209. items: [
  210. _buildMenuItem(
  211. icon: Icons.help_outline,
  212. title: '帮助中心',
  213. subtitle: '常见问题和帮助文档',
  214. onTap: () {},
  215. ),
  216. _buildMenuItem(
  217. icon: Icons.info_outline,
  218. title: '关于我们',
  219. subtitle: '了解应用信息',
  220. onTap: () {},
  221. ),
  222. _buildMenuItem(
  223. icon: Icons.logout,
  224. title: '退出登录',
  225. subtitle: '安全退出当前账号',
  226. onTap: () async {
  227. await authProvider.logout();
  228. if (mounted) {
  229. Navigator.of(context).pushReplacementNamed('/');
  230. }
  231. },
  232. ),
  233. ],
  234. ),
  235. const SizedBox(height: 20),
  236. // 版本信息
  237. Padding(
  238. padding: const EdgeInsets.symmetric(vertical: 20),
  239. child: Text(
  240. '版本 v1.0.0',
  241. style: TextStyle(
  242. fontSize: 12,
  243. color: Colors.grey[500],
  244. ),
  245. ),
  246. ),
  247. ],
  248. ),
  249. ),
  250. ],
  251. ),
  252. ),
  253. bottomNavigationBar: const BottomNavBar(initialIndex: 3),
  254. );
  255. }
  256. Widget _buildStatItem(String label, String value) {
  257. return Expanded(
  258. child: Column(
  259. children: [
  260. Text(
  261. value,
  262. style: const TextStyle(
  263. fontSize: 18,
  264. fontWeight: FontWeight.bold,
  265. ),
  266. ),
  267. const SizedBox(height: 4),
  268. Text(
  269. label,
  270. style: TextStyle(
  271. fontSize: 12,
  272. color: Colors.grey[600],
  273. ),
  274. ),
  275. ],
  276. ),
  277. );
  278. }
  279. Widget _buildVerticalDivider() {
  280. return Container(
  281. width: 1,
  282. height: 40,
  283. color: Colors.grey[300],
  284. margin: const EdgeInsets.symmetric(horizontal: 16),
  285. );
  286. }
  287. Widget _buildMenuCard({
  288. required String title,
  289. required List<Widget> items,
  290. }) {
  291. return Card(
  292. elevation: 2,
  293. shape: RoundedRectangleBorder(
  294. borderRadius: BorderRadius.circular(12),
  295. ),
  296. child: Padding(
  297. padding: const EdgeInsets.all(16),
  298. child: Column(
  299. crossAxisAlignment: CrossAxisAlignment.start,
  300. children: [
  301. Text(
  302. title,
  303. style: const TextStyle(
  304. fontSize: 16,
  305. fontWeight: FontWeight.bold,
  306. ),
  307. ),
  308. const SizedBox(height: 12),
  309. Column(children: items),
  310. ],
  311. ),
  312. ),
  313. );
  314. }
  315. Widget _buildMenuItem({
  316. required IconData icon,
  317. required String title,
  318. required String subtitle,
  319. required VoidCallback onTap,
  320. }) {
  321. return ListTile(
  322. contentPadding: EdgeInsets.zero,
  323. leading: Icon(icon),
  324. title: Text(title),
  325. subtitle: Text(subtitle),
  326. trailing: const Icon(Icons.chevron_right),
  327. onTap: onTap,
  328. );
  329. }
  330. }