character_custom_detail_page.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. import 'package:cached_network_image/cached_network_image.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:keyboard/base/base_page.dart';
  4. import 'package:flutter/material.dart';
  5. import '../../../data/bean/custom_config_info.dart';
  6. import '../../../resource/assets.gen.dart';
  7. import '../../../resource/string.gen.dart';
  8. import '../../../router/app_pages.dart';
  9. import '../../../utils/styles.dart';
  10. import 'character_custom_detail_controller.dart';
  11. import 'package:get/get.dart';
  12. class CharacterCustomDetailPage
  13. extends BasePage<CharacterCustomDetailController> {
  14. const CharacterCustomDetailPage({super.key});
  15. static void start({
  16. List<Hobbies>? hobbiesSelectLabels,
  17. List<CharactersList>? characterSelectLabels,
  18. String? characterCustomName,
  19. }) {
  20. Get.toNamed(
  21. RoutePath.characterCustomDetail,
  22. arguments: {
  23. 'hobbiesSelectLabels': hobbiesSelectLabels,
  24. 'characterSelectLabels': characterSelectLabels,
  25. 'characterCustomName': characterCustomName,
  26. },
  27. );
  28. }
  29. @override
  30. bool immersive() {
  31. return true;
  32. }
  33. @override
  34. Widget buildBody(BuildContext context) {
  35. return Stack(
  36. children: [
  37. Container(
  38. child: Assets.images.bgCharacterCustomDetail.image(
  39. width: double.infinity,
  40. fit: BoxFit.fill,
  41. ),
  42. ),
  43. SafeArea(
  44. child: Container(
  45. color: Colors.transparent,
  46. alignment: Alignment.topCenter,
  47. child: Stack(
  48. children: [
  49. Column(
  50. children: [
  51. _buildTitle(),
  52. SizedBox(height: 42.h),
  53. Expanded(
  54. child: Container(
  55. decoration: ShapeDecoration(
  56. color: Color(0xFFF6F5FA),
  57. shape: RoundedRectangleBorder(
  58. borderRadius: BorderRadius.only(
  59. topLeft: Radius.circular(20.r),
  60. topRight: Radius.circular(20.r),
  61. ),
  62. ),
  63. ),
  64. child: SingleChildScrollView(
  65. child: Column(
  66. children: [
  67. _buildNameCard(),
  68. SizedBox(height: 34.h),
  69. _buildGenderCard(),
  70. SizedBox(height: 10.h),
  71. _buildBirthdayCard(),
  72. SizedBox(height: 10.h),
  73. _hobbiesCard(),
  74. SizedBox(height: 18.h),
  75. _characterCard(),
  76. ],
  77. ),
  78. ),
  79. ),
  80. ),
  81. Container(
  82. color: Color(0xFFF6F5FA),
  83. child: _buildUnlockButton(),
  84. ),
  85. ],
  86. ),
  87. Positioned(left: 16.w, top: 60.h, child: _buildAvatar()),
  88. Positioned(left: 68.w, top: 112.h, child: _buildAvatarSwitch()),
  89. ],
  90. ),
  91. ),
  92. ),
  93. ],
  94. );
  95. }
  96. _buildTitle() {
  97. return Container(
  98. alignment: Alignment.centerLeft,
  99. padding: EdgeInsets.only(top: 12.h, left: 16.w),
  100. child: GestureDetector(
  101. onTap: controller.clickBack,
  102. child: Assets.images.iconMineBackArrow.image(width: 24.w, height: 24.w),
  103. ),
  104. );
  105. }
  106. _buildNameCard() {
  107. return Container(
  108. padding: EdgeInsets.only(left: 104.w, top: 14.h),
  109. child: Row(
  110. crossAxisAlignment: CrossAxisAlignment.end,
  111. children: [
  112. Text(
  113. controller.characterCustomName,
  114. textAlign: TextAlign.center,
  115. style: TextStyle(
  116. color: Colors.black.withAlpha(204),
  117. fontSize: 18.sp,
  118. fontWeight: FontWeight.w500,
  119. ),
  120. ),
  121. Container(
  122. child: Assets.images.iconCharacterCustomDetailEdit.image(
  123. width: 20.r,
  124. height: 20.r,
  125. ),
  126. ),
  127. ],
  128. ),
  129. );
  130. }
  131. _buildAvatar() {
  132. return GestureDetector(
  133. onTap: controller.nextAvatar,
  134. child: Container(
  135. width: 72.r,
  136. height: 72.r,
  137. decoration: ShapeDecoration(
  138. shape: OvalBorder(side: BorderSide(width: 2, color: Colors.white)),
  139. ),
  140. child:CachedNetworkImage(imageUrl: controller.avatarUrl,width: 72.r,height: 72.r,),
  141. ));
  142. }
  143. _buildAvatarSwitch() {
  144. return GestureDetector(
  145. onTap: controller.nextAvatar,
  146. child: SizedBox(
  147. width: 22.r,
  148. height: 22.r,
  149. child: Assets.images.iconCharacterCustomDetailSwitch.image(
  150. width: 22.r,
  151. height: 22.r,
  152. ),
  153. ),
  154. );
  155. }
  156. // 性别
  157. Widget _buildGenderCard() {
  158. return _buildListItem(
  159. onTap: () {
  160. debugPrint('点击了性别');
  161. },
  162. firstWidget: Text('性别', style: Styles.getTextStyleBlack204W400(14.sp)),
  163. bottomWidget: Row(
  164. children: [
  165. Assets.images.iconCharacterCustomDetailMale.image(
  166. width: 24.w,
  167. height: 24.w,
  168. ),
  169. SizedBox(width: 6.w),
  170. Text('男', style: Styles.getTextStyleBlack204W400(14.sp)),
  171. Spacer(),
  172. Assets.images.iconArrowRight.image(width: 24.w, height: 24.w),
  173. ],
  174. ),
  175. );
  176. }
  177. Widget _buildBirthdayCard() {
  178. return _buildListItem(
  179. onTap: () {
  180. debugPrint('点击了生日');
  181. },
  182. firstWidget: Text('出生日期', style: Styles.getTextStyleBlack204W400(14.sp)),
  183. bottomWidget: Row(
  184. children: [
  185. Text('1998-12-16', style: Styles.getTextStyleBlack204W400(14.sp)),
  186. SizedBox(width: 12.w),
  187. Text('22岁', style: Styles.getTextStyleBlack204W400(14.sp)),
  188. Spacer(),
  189. Assets.images.iconArrowRight.image(width: 24.w, height: 24.w),
  190. ],
  191. ),
  192. );
  193. }
  194. Widget _hobbiesCard() {
  195. return _buildTagCard(
  196. title: '兴趣爱好',
  197. labels: controller.hobbiesSelectLabels,
  198. isShowEmoji: true,
  199. onTap: () {
  200. debugPrint('点击了兴趣爱好');
  201. },
  202. );
  203. }
  204. Widget _characterCard() {
  205. return _buildTagCard(
  206. title: '性格',
  207. labels: controller.characterSelectLabels,
  208. isShowEmoji: false,
  209. onTap: () {
  210. debugPrint('点击了性格');
  211. },
  212. );
  213. }
  214. Widget _buildUnlockButton() {
  215. return GestureDetector(
  216. onTap: () {
  217. controller.clickUnlockButton();
  218. },
  219. child: Container(
  220. width: double.infinity,
  221. margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
  222. height: 48.h,
  223. alignment: Alignment.center,
  224. decoration: ShapeDecoration(
  225. color: const Color(0xFF7D46FC),
  226. shape: RoundedRectangleBorder(
  227. borderRadius: BorderRadius.circular(50.r),
  228. ),
  229. ),
  230. child: Row(
  231. mainAxisAlignment: MainAxisAlignment.center,
  232. children: [
  233. Assets.images.iconCharacterCustomDetailLock.image(
  234. width: 22.w,
  235. height: 22.w,
  236. ),
  237. Text(
  238. StringName.unlockExclusiveCharacter,
  239. textAlign: TextAlign.center,
  240. style: Styles.getTextStyleWhiteW500(16.sp),
  241. ),
  242. ],
  243. ),
  244. ),
  245. );
  246. }
  247. // 列表项
  248. Widget _buildListItem({
  249. required Widget firstWidget,
  250. required Widget bottomWidget,
  251. VoidCallback? onTap,
  252. }) {
  253. return Container(
  254. padding: EdgeInsets.only(
  255. left: 12.w,
  256. right: 12.w,
  257. top: 14.h,
  258. bottom: 14.h,
  259. ),
  260. margin: EdgeInsets.only(left: 16.w, right: 16.w),
  261. width: double.infinity,
  262. decoration: ShapeDecoration(
  263. color: Colors.white,
  264. shape: RoundedRectangleBorder(
  265. borderRadius: BorderRadius.circular(12.r),
  266. ),
  267. ),
  268. child: Column(
  269. crossAxisAlignment: CrossAxisAlignment.start,
  270. mainAxisAlignment: MainAxisAlignment.center,
  271. children: [
  272. firstWidget,
  273. _buildDivider(),
  274. GestureDetector(
  275. behavior: HitTestBehavior.opaque,
  276. onTap: onTap,
  277. child: bottomWidget,
  278. ),
  279. ],
  280. ),
  281. );
  282. }
  283. // 下划线
  284. Widget _buildDivider() {
  285. return Container(
  286. margin: EdgeInsets.only(top: 8.h, bottom: 8.h),
  287. width: 304.w,
  288. decoration: ShapeDecoration(
  289. shape: RoundedRectangleBorder(
  290. side: BorderSide(
  291. width: 1.r,
  292. strokeAlign: BorderSide.strokeAlignCenter,
  293. color: const Color(0xFFF5F4F9),
  294. ),
  295. ),
  296. ),
  297. );
  298. }
  299. Widget _buildTagCard({
  300. required String title,
  301. required List<dynamic> labels,
  302. required bool isShowEmoji,
  303. VoidCallback? onTap,
  304. }) {
  305. return _buildListItem(
  306. onTap: onTap,
  307. firstWidget: Text(title, style: Styles.getTextStyleBlack204W400(14.sp)),
  308. bottomWidget: Row(
  309. children: [
  310. Expanded(
  311. child: Wrap(
  312. spacing: 8.w,
  313. runSpacing: 8.h,
  314. children: labels.asMap().entries.map((entry) {
  315. int index = entry.key;
  316. var label = entry.value;
  317. // 根据索引设置不同的颜色
  318. Color color;
  319. switch (index) {
  320. case 0:
  321. color = Color(0xFFFEECE0);
  322. break;
  323. case 1:
  324. color = Color(0xFFE8E4FC);
  325. break;
  326. case 2:
  327. color = Color(0xFFE8F8E0);
  328. break;
  329. default:
  330. color = Color(0xFFFEECE0);
  331. }
  332. return _buildColorTag(
  333. color: color,
  334. name: label.name,
  335. emoji: label.emoji,
  336. isShowEmoji: isShowEmoji,
  337. );
  338. }).toList(),
  339. ),
  340. ),
  341. SizedBox(width: 8.w),
  342. Assets.images.iconArrowRight.image(width: 24.w, height: 24.w),
  343. ],
  344. ),
  345. );
  346. }
  347. Widget _buildColorTag({
  348. required Color color,
  349. String? name,
  350. String? emoji,
  351. bool isShowEmoji = true,
  352. }) {
  353. return Container(
  354. padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 3.h),
  355. decoration: ShapeDecoration(
  356. color: color,
  357. shape: RoundedRectangleBorder(
  358. borderRadius: BorderRadius.circular(23.r),
  359. ),
  360. ),
  361. child: Row(
  362. mainAxisSize: MainAxisSize.min,
  363. mainAxisAlignment: MainAxisAlignment.center,
  364. crossAxisAlignment: CrossAxisAlignment.center,
  365. children: [
  366. if (emoji != null&&isShowEmoji)
  367. Text(emoji, style: Styles.getTextStyleBlack204W400(14.sp)),
  368. if (emoji != null && name != null) SizedBox(width: 4.w),
  369. if (name != null)
  370. Text(name, style: Styles.getTextStyleBlack204W400(14.sp)),
  371. ],
  372. ),
  373. );
  374. }
  375. }