profile_page.dart 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter/material.dart';
  3. import 'package:flutter_screenutil/flutter_screenutil.dart';
  4. import 'package:get/get.dart';
  5. import 'package:keyboard/base/base_page.dart';
  6. import 'package:keyboard/data/bean/keyboard_info.dart';
  7. import 'package:keyboard/module/profile/profile_controller.dart';
  8. import 'package:keyboard/utils/intimacy_util.dart';
  9. import '../../resource/assets.gen.dart';
  10. import '../../resource/string.gen.dart';
  11. import '../../router/app_pages.dart';
  12. import '../../utils/styles.dart';
  13. class ProfilePage extends BasePage<ProfileController> {
  14. const ProfilePage({super.key});
  15. static start() {
  16. Get.toNamed(RoutePath.profile);
  17. }
  18. @override
  19. Color backgroundColor() {
  20. return const Color(0xFFF6F5FA);
  21. }
  22. @override
  23. immersive() {
  24. return true;
  25. }
  26. @override
  27. Widget buildBody(BuildContext context) {
  28. return Stack(
  29. children: [
  30. SafeArea(
  31. child: CustomScrollView(
  32. physics: const BouncingScrollPhysics(), // 更流畅的滚动
  33. slivers: [
  34. SliverToBoxAdapter(
  35. child: Column(
  36. crossAxisAlignment: CrossAxisAlignment.start,
  37. children: [_buildTitle(), SizedBox(height: 26.h)],
  38. ),
  39. ),
  40. // 键盘列表
  41. Obx(() {
  42. if (controller.keyboardInfoList.isEmpty) {
  43. return const SliverToBoxAdapter(child: SizedBox());
  44. }
  45. return SliverList(
  46. delegate: SliverChildBuilderDelegate((context, index) {
  47. KeyboardInfo keyboardInfo =
  48. controller.keyboardInfoList[index];
  49. return Obx(() {
  50. return _buildKeyboardListItem(
  51. keyboardInfo,
  52. keyboardInfo.id ==
  53. controller.currentCustomKeyboardInfo.id,
  54. );
  55. });
  56. }, childCount: controller.keyboardInfoList.length),
  57. );
  58. }),
  59. ],
  60. ),
  61. ),
  62. Positioned(
  63. bottom: 20.h,
  64. left: 16.w,
  65. right: 16.w,
  66. child: InkWell(
  67. onTap: () {
  68. controller.clickSaveButton();
  69. },
  70. child: Container(
  71. height: 48.h,
  72. alignment: Alignment.center,
  73. decoration: Styles.getActivateButtonDecoration(31.r),
  74. child: Text(
  75. StringName.profileSave,
  76. style: Styles.getTextStyleWhiteW500(16.sp),
  77. ),
  78. ),
  79. ),
  80. ),
  81. // 背景图片
  82. IgnorePointer(child: Assets.images.bgMine.image(width: 360.w)),
  83. ],
  84. );
  85. }
  86. _buildKeyboardListItem(KeyboardInfo keyboardInfo, bool isChoose) {
  87. return GestureDetector(
  88. onTap: () {
  89. controller.clickOnChangeKeyboard(keyboardInfo);
  90. },
  91. child: Container(
  92. height: 164.h,
  93. margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 12.h),
  94. decoration:
  95. isChoose
  96. ? ShapeDecoration(
  97. gradient: LinearGradient(
  98. begin: Alignment(0.02, 0.04),
  99. end: Alignment(1.00, 1.00),
  100. colors: [const Color(0xFFE7A0FF), const Color(0xFFAB8FFA)],
  101. ),
  102. shape: RoundedRectangleBorder(
  103. borderRadius: BorderRadius.circular(22.r),
  104. ),
  105. shadows: [
  106. BoxShadow(
  107. color: Color(0x1CD6C1FF),
  108. blurRadius: 4.r,
  109. offset: Offset(0, 4.r),
  110. spreadRadius: 0,
  111. ),
  112. ],
  113. )
  114. : ShapeDecoration(
  115. color: Colors.white,
  116. shape: RoundedRectangleBorder(
  117. borderRadius: BorderRadius.circular(20.r),
  118. ),
  119. ),
  120. child: Stack(
  121. children: [
  122. isChoose
  123. ? Opacity(
  124. opacity: 0.1,
  125. child: Assets.images.bgProfileSelected.image(),
  126. )
  127. : SizedBox(),
  128. Column(
  129. crossAxisAlignment: CrossAxisAlignment.center,
  130. children: [
  131. Padding(
  132. padding: EdgeInsets.only(left: 16.w, right: 16.w, top: 10.h),
  133. child: Row(
  134. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  135. children: [
  136. Text(
  137. '我&${keyboardInfo.name}',
  138. style: TextStyle(
  139. color: const Color(0xFF202020),
  140. fontSize: 16.sp,
  141. fontWeight: FontWeight.w700,
  142. ),
  143. ),
  144. Container(
  145. height: 26.h,
  146. width: 55.w,
  147. decoration: ShapeDecoration(
  148. color:
  149. isChoose ? Colors.white : const Color(0xFFF1F1F1),
  150. shape: RoundedRectangleBorder(
  151. borderRadius: BorderRadius.circular(50.r),
  152. ),
  153. ),
  154. child: Row(
  155. mainAxisAlignment: MainAxisAlignment.center,
  156. children: [
  157. Assets.images.iconProfileEdit.image(
  158. width: 10.w,
  159. height: 10.w,
  160. ),
  161. SizedBox(width: 4.w),
  162. Text(
  163. '编辑',
  164. style: TextStyle(
  165. color: Colors.black.withAlpha(178),
  166. fontSize: 11,
  167. fontWeight: FontWeight.w500,
  168. ),
  169. ),
  170. ],
  171. ),
  172. ),
  173. ],
  174. ),
  175. ),
  176. SizedBox(height: 10.h),
  177. Padding(
  178. padding: EdgeInsets.symmetric(horizontal: 16.w),
  179. child: Divider(
  180. height: 1.h,
  181. color: isChoose ? Colors.transparent : Color(0xffF5F5F5),
  182. ),
  183. ),
  184. Expanded(
  185. child: Container(
  186. margin:
  187. isChoose
  188. ? EdgeInsets.only(
  189. left: 4.w,
  190. right: 4.w,
  191. bottom: 4.w,
  192. )
  193. : EdgeInsets.all(0),
  194. decoration: ShapeDecoration(
  195. color: Colors.white,
  196. shape: RoundedRectangleBorder(
  197. borderRadius: BorderRadius.circular(20.r),
  198. ),
  199. shadows: [
  200. BoxShadow(
  201. color: Color(0x1CD6C1FF),
  202. blurRadius: 4.r,
  203. offset: Offset(0, 4),
  204. spreadRadius: 0,
  205. ),
  206. ],
  207. ),
  208. child: Row(
  209. mainAxisAlignment: MainAxisAlignment.center,
  210. children: [
  211. Stack(
  212. children: [
  213. Container(
  214. width: 78.w,
  215. height: 78.w,
  216. decoration: ShapeDecoration(
  217. color:
  218. controller.userGender == 1
  219. ? Color(0xFFB7B6FF)
  220. : null,
  221. gradient:
  222. controller.userGender == 1
  223. ? null
  224. : LinearGradient(
  225. begin: Alignment(0.50, -0.00),
  226. end: Alignment(0.50, 1.00),
  227. colors: [
  228. const Color(0xFFEBE6FF),
  229. const Color(0xFFFFE6FE),
  230. ],
  231. ),
  232. shape: RoundedRectangleBorder(
  233. side: BorderSide(
  234. width: 1.5.w,
  235. color: Colors.white,
  236. ),
  237. borderRadius: BorderRadius.circular(40.r),
  238. ),
  239. ),
  240. child:
  241. controller.userInfo?.imageUrl?.isNotEmpty ==
  242. true
  243. ? ClipRRect(
  244. borderRadius: BorderRadius.circular(
  245. 40.r,
  246. ),
  247. child: CachedNetworkImage(
  248. width: 78.w,
  249. height: 78.w,
  250. imageUrl:
  251. controller.userInfo?.imageUrl ??
  252. "",
  253. ),
  254. )
  255. : SizedBox(),
  256. ),
  257. Positioned(
  258. top: 0,
  259. right: 0,
  260. child:
  261. controller.userGender == 1
  262. ? Assets.images.iconProfileMale.image(
  263. width: 20.w,
  264. height: 20.w,
  265. )
  266. : Assets.images.iconProfileFemale.image(
  267. width: 20.w,
  268. height: 20.w,
  269. ),
  270. ),
  271. ],
  272. ),
  273. SizedBox(width: 8.w),
  274. // 爱心
  275. Container(
  276. width: 87.w,
  277. height: 71.h,
  278. decoration: BoxDecoration(
  279. image: DecorationImage(
  280. image: Assets.images.bgProfileLove.provider(),
  281. ),
  282. ),
  283. child: Column(
  284. children: [
  285. SizedBox(height: 45.h),
  286. Container(
  287. width: 47.w,
  288. height: 19.h,
  289. decoration: ShapeDecoration(
  290. color: Colors.white,
  291. shape: RoundedRectangleBorder(
  292. side: BorderSide(
  293. width: 1.18.w,
  294. color: const Color(0xFFFD649B),
  295. ),
  296. borderRadius: BorderRadius.circular(
  297. 12.36.r,
  298. ),
  299. ),
  300. ),
  301. child:
  302. (keyboardInfo.intimacy != null)
  303. ? Center(
  304. child: Text(
  305. IntimacyUtil.getIntimacyName(
  306. keyboardInfo.intimacy!,
  307. ),
  308. style: TextStyle(
  309. color: const Color(0xFFFF73E0),
  310. fontSize: 11.sp,
  311. fontWeight: FontWeight.w500,
  312. ),
  313. ),
  314. )
  315. : SizedBox(),
  316. ),
  317. ],
  318. ),
  319. ),
  320. SizedBox(width: 8.w),
  321. keyboardInfo.avatar?.isNotEmpty == true
  322. ? Stack(
  323. children: [
  324. Container(
  325. width: 78.w,
  326. height: 78.w,
  327. decoration: ShapeDecoration(
  328. color:
  329. keyboardInfo.gender == 1
  330. ? Color(0xFFB7B6FF)
  331. : null,
  332. gradient:
  333. keyboardInfo.gender == 1
  334. ? null
  335. : LinearGradient(
  336. begin: Alignment(0.50, -0.00),
  337. end: Alignment(0.50, 1.00),
  338. colors: [
  339. const Color(0xFFEBE6FF),
  340. const Color(0xFFFFE6FE),
  341. ],
  342. ),
  343. shape: RoundedRectangleBorder(
  344. side: BorderSide(
  345. width: 1.5.w,
  346. color: Colors.white,
  347. ),
  348. borderRadius: BorderRadius.circular(40.r),
  349. ),
  350. ),
  351. child: ClipRRect(
  352. borderRadius: BorderRadius.circular(40.r),
  353. child: CachedNetworkImage(
  354. imageUrl: keyboardInfo.avatar!,
  355. ),
  356. ),
  357. ),
  358. Positioned(
  359. top: 0,
  360. left: 0,
  361. child:
  362. keyboardInfo.gender == 1
  363. ? Assets.images.iconProfileMale.image(
  364. width: 20.w,
  365. height: 20.w,
  366. )
  367. : Assets.images.iconProfileFemale
  368. .image(width: 20.w, height: 20.w),
  369. ),
  370. ],
  371. )
  372. : SizedBox(width: 78.w, height: 78.w),
  373. ],
  374. ),
  375. ),
  376. ),
  377. ],
  378. ),
  379. ],
  380. ),
  381. ),
  382. );
  383. }
  384. _buildTitle() {
  385. return Container(
  386. alignment: Alignment.centerLeft,
  387. padding: EdgeInsets.only(top: 12.h, left: 16.w, right: 16.w),
  388. child: Row(
  389. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  390. children: [
  391. GestureDetector(
  392. onTap: controller.clickBack,
  393. child: Assets.images.iconMineBackArrow.image(
  394. width: 24.w,
  395. height: 24.w,
  396. ),
  397. ),
  398. Text("我", style: Styles.getTextStyleBlack204W500(17.sp)),
  399. SizedBox(),
  400. GestureDetector(
  401. onTap: controller.clickAddButton,
  402. child: Assets.images.iconProfileAdd.image(
  403. width: 24.w,
  404. height: 24.w,
  405. ),
  406. ),
  407. ],
  408. ),
  409. );
  410. }
  411. }