import 'package:dotted_border/dotted_border.dart'; import 'package:flutter/src/widgets/framework.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:keyboard/module/change/character/change_character_controller.dart'; import '../../../base/base_page.dart'; import '../../../data/bean/custom_config_info.dart'; import 'package:get/get.dart'; import 'package:flutter/material.dart'; import '../../../resource/assets.gen.dart'; import '../../../resource/string.gen.dart'; import '../../../router/app_pages.dart'; import '../../../utils/styles.dart'; class ChangeCharacterPage extends BasePage { const ChangeCharacterPage({super.key}); static Future start({List? characters}) async { return Get.toNamed( RoutePath.changeCharacters, arguments: {"characters": characters}, ); } @override bool immersive() { return true; } @override Color backgroundColor() { return const Color(0xFFF6F5FA); } @override Widget buildBody(BuildContext context) { return Stack( children: [ IgnorePointer(child: Assets.images.bgMine.image(width: 360.w)), SafeArea( child: Stack( children: [ Column( children: [ _buildTitle(), SizedBox(height: 40.h), Text( StringName.characterKeywords, style: Styles.getTextStyleBlack204W500(22.sp), ), SizedBox(height: 50.h), _buildCurrentCharacterLabels(), SizedBox(height: 20.h), _buildDivider(), Expanded( child: SingleChildScrollView( child: _buildSelectionPage( items: controller.characterLabelsList, selectedLabels: controller.characterSelectLabels, onSelected: (item) { controller.selectCharacter(item); }, isCustomEnabled: true, isShowEmoji: true, ), ), ), SizedBox(height: 100.h), ], ), Align( alignment: Alignment.bottomCenter, child: Container( margin: EdgeInsets.only(bottom: 32.h), child: Obx(() { return _buildSaveButton( onTap: () { controller.clickSave(); }, isEnable: controller.characterSelectLabels.isNotEmpty, ); }), ), ), ], ), ), ], ); } _buildTitle() { return Container( alignment: Alignment.centerLeft, padding: EdgeInsets.only(top: 12.h, left: 16.w, right: 16.w), child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ GestureDetector( onTap: controller.clickBack, child: Assets.images.iconMineBackArrow.image( width: 24.w, height: 24.w, ), ), ], ), ); } Widget _buildSaveButton({required VoidCallback onTap, required isEnable}) { return GestureDetector( onTap: () { onTap(); }, child: Container( width: 260.w, height: 48.h, decoration: isEnable ? Styles.getActivateButtonDecoration(31.r) : Styles.getInactiveButtonDecoration(31.r), child: Center( child: Text( '保存', style: TextStyle( color: Colors.white, fontSize: 16.sp, fontWeight: FontWeight.w500, ), ), ), ), ); } Widget _buildSelectionPage({ required List items, required RxList selectedLabels, required Function(dynamic) onSelected, required bool isCustomEnabled, required bool isShowEmoji, }) { return Obx(() { return Column( children: [ Container( margin: EdgeInsets.only(top: 20.h, left: 18.w, right: 18.w), alignment: Alignment.center, child: GridView.count( physics: NeverScrollableScrollPhysics(), shrinkWrap: true, crossAxisCount: 3, crossAxisSpacing: 6.r, mainAxisSpacing: 10.r, childAspectRatio: 2.6, children: [ ...items.map((item) { final emoji = item.emoji ?? ""; final name = item.name ?? ""; return Obx(() { bool isSelected = selectedLabels.contains(item); return ChoiceChip( padding: EdgeInsets.zero, label: SizedBox( width: 140.w, child: Center( child: Text( isShowEmoji ? "$emoji$name" : name, overflow: TextOverflow.ellipsis, maxLines: 1, style: TextStyle( color: isSelected ? Color(0xFF7D46FC) : Colors.black.withValues(alpha: 0.8), fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ), ), showCheckmark: false, selected: isSelected, selectedColor: Color(0xFFEDE8FF), backgroundColor: Colors.white, shape: RoundedRectangleBorder( side: BorderSide(width: 0.w, color: Colors.transparent), borderRadius: BorderRadius.circular(31.r), ), onSelected: (selected) { onSelected(item); }, ); }); }), ], ), ), ], ); }); } Widget _buildDivider() { return Container( margin: EdgeInsets.only(top: 8.h, bottom: 8.h), width: 304.w, decoration: ShapeDecoration( shape: RoundedRectangleBorder( side: BorderSide( width: 0.5.w, strokeAlign: BorderSide.strokeAlignCenter, color: const Color(0xffDDDCE1), ), ), ), ); } // 添加爱好 Widget _buildCustom(VoidCallback onCustomClick) { return GestureDetector( onTap: onCustomClick, child: DottedBorder( color: const Color(0xFFC9C2DB), strokeWidth: 1.0.w, padding: EdgeInsets.symmetric(horizontal: 11.w, vertical: 8.h), borderType: BorderType.RRect, radius: Radius.circular(70.r), child: Container( alignment: Alignment.center, child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Assets.images.iconCharacterCustomPlus.image( width: 18.w, height: 18.w, ), Text( StringName.characterKeywords, style: TextStyle( color: const Color(0xFFC9C2DB), fontSize: 14.sp, fontWeight: FontWeight.w500, ), ), ], ), ), ), ); } _buildCurrentCharacterLabels() { return Obx(() { return Container( padding: EdgeInsets.only(top: 14.h, bottom: 14.h), width: 326.w, decoration: ShapeDecoration( color: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(38.50.r), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: List.generate(3, (index) { final character = (index < controller.characterSelectLabels.length) ? controller.characterSelectLabels[index] : null; return Padding( padding: EdgeInsets.symmetric(horizontal: 4.w), child: _buildCharacterItem(character), ); }), ), ); }); } //当个选中的标签 Widget _buildCharacterItem(CharactersList? character) { final hasEmoji = character?.emoji != null; final hasName = character?.name != null; return Stack( children: [ Column( children: [ SizedBox(height: 2.h), Container( width: 92.6.w, height: 40.h, alignment: Alignment.center, decoration: ShapeDecoration( color: const Color(0xFFF6F5FF), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(70.r), ), ), child: hasEmoji ? Text(character!.emoji!) : Assets.images.iconChangeCharacterEmpty.image( width: 14.w, height: 18.w, ), ), if (hasName) Padding( padding: EdgeInsets.only(top: 13.h), child: Text( character!.name!, style: TextStyle( color: Colors.black.withOpacity(0.8), fontSize: 14.sp, fontWeight: FontWeight.w400, ), ), ), ], ), if (hasEmoji) Positioned( right: 0, top: 0, child: InkWell( onTap: () { controller.characterSelectLabels.remove(character); }, child: Assets.images.iconChangeCharacterUnselect.image( width: 17.w, height: 17.w, ) ), ), ], ); } }