| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- import 'package:dotted_border/dotted_border.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:get/get.dart';
- import 'package:keyboard/base/base_page.dart';
- import 'package:keyboard/module/keyboard_manage/keyboard_manage_controller.dart';
- import 'package:keyboard/resource/string.gen.dart';
- import 'package:reorderables/reorderables.dart';
- import '../../data/bean/character_info.dart';
- import '../../resource/assets.gen.dart';
- import '../../router/app_pages.dart';
- import '../../widget/gradient_rect_slider_track_shape.dart';
- import '../../widget/tab_custom_gradient_indicator.dart';
- class KeyboardManagePage extends BasePage<KeyboardManageController> {
- const KeyboardManagePage({super.key});
- @override
- immersive() {
- return true;
- }
- static start() {
- Get.toNamed(RoutePath.keyboardManage);
- }
- @override
- Widget buildBody(BuildContext context) {
- return Container(
- decoration: BoxDecoration(
- image: DecorationImage(
- image: Assets.images.bgKeyboardManage.provider(),
- fit: BoxFit.fill,
- ),
- ),
- child: SafeArea(
- child: Container(
- alignment: Alignment.topCenter,
- child: Column(
- children: [
- // TabBar
- _buildTitle(),
- SizedBox(height: 10.h),
- Expanded(
- child: Container(
- decoration: ShapeDecoration(
- color: Colors.white,
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.only(
- topLeft: Radius.circular(20.r),
- topRight: Radius.circular(20.r),
- ),
- ),
- ),
- child: PageView(
- controller: controller.pageController,
- onPageChanged: (index) {
- controller.switchPageKeyboardType(index);
- },
- children: [
- _buildCustomKeyboardSettings(),
- _buildGeneralKeyboardSettings(),
- ],
- ),
- ),
- ),
- ],
- ),
- ),
- ),
- );
- }
- Widget _buildTitle() {
- return Padding(
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- child: Row(
- children: [
- GestureDetector(
- onTap: controller.clickBack,
- child: Assets.images.iconMineBackArrow.image(
- width: 24.w,
- height: 24.w,
- ),
- ),
- Expanded(
- child: TabBar(
- // onTap: controller.switchTabKeyboardType,
- controller: controller.tabController,
- tabs:
- controller.keyboardManageType
- .map((e) => Tab(text: e))
- .toList(),
- dividerHeight: 0,
- indicator: TabCustomGradientIndicator(),
- labelStyle: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 17.sp,
- fontWeight: FontWeight.w500,
- ),
- unselectedLabelStyle: TextStyle(
- color: Colors.black.withAlpha(102),
- fontSize: 17.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- SizedBox(width: 24.w),
- ],
- ),
- );
- }
- Widget _buildCustomKeyboardSettings() {
- return Column(
- children: [
- Expanded(
- child: SingleChildScrollView(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- _buildDropdownButton(), // 下拉框
- _buildIntimacySlider(isCustom: true), // 亲密度模块
- _buildKeyboardCharacter(isCustom: true), // 键盘人设
- ],
- ),
- ),
- ),
- _buildSaveButton(isCustom: true),
- ],
- );
- }
- Widget _buildGeneralKeyboardSettings() {
- return Column(
- children: [
- Expanded(
- child: SingleChildScrollView(
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- _buildIntimacySlider(isCustom: false), // 亲密度模块
- _buildKeyboardCharacter(isCustom: false), // 键盘人设
- ],
- ),
- ),
- ),
- _buildSaveButton(isCustom: false),
- ],
- );
- }
- Widget _buildDropdownButton() {
- return Obx(() {
- return Padding(
- padding: EdgeInsets.only(left: 16.w, top: 24.h, right: 16.w),
- child: Row(
- children: [
- Text(
- "自己&",
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- DropdownButton<String>(
- underline: Container(height: 0),
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- ),
- icon: Assets.images.iconCharacterArrowDown.image(
- width: 20.r,
- height: 20.r,
- ),
- value: controller.currentCustomKeyboardInfo.name,
- onChanged: (String? newValue) {
- controller.switchCustomKeyboard(newValue);
- },
- items: List.generate(controller.customKeyboardInfoList.length, (
- index,
- ) {
- String? value = controller.customKeyboardInfoList[index].name;
- return DropdownMenuItem<String>(
- value: value,
- child: Column(
- crossAxisAlignment: CrossAxisAlignment.start,
- mainAxisSize: MainAxisSize.min,
- children: [
- Padding(
- padding: EdgeInsets.symmetric(vertical: 8),
- child: Text(
- value ?? "",
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- if (index != controller.customKeyboardInfoList.length - 1)
- Divider(
- color: Color(0xFFF6F6F6),
- thickness: 1,
- height: 1,
- ),
- ],
- ),
- );
- }),
- ),
- ],
- ),
- );
- });
- }
- Widget _buildIntimacySlider({required bool isCustom}) {
- return // 亲密度模块
- Container(
- margin: EdgeInsets.only(left: 16.w, top: 24.h, right: 16.w),
- padding: EdgeInsets.only(
- left: 16.w,
- top: 23.h,
- right: 16.w,
- bottom: 26.h,
- ),
- decoration: BoxDecoration(
- image: DecorationImage(
- image: Assets.images.bgKeyboardManageIntimacy.provider(),
- fit: BoxFit.fill,
- ),
- borderRadius: BorderRadius.circular(10.r),
- ),
- child: Column(
- children: [
- // 亲密度
- Row(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Assets.images.iconKeyboardManageFavorite.image(
- width: 20.w,
- height: 20.w,
- ),
- Assets.images.iconKeyboardManageIntimacyText.image(
- width: 48.w,
- height: 19.h,
- ),
- const Spacer(),
- Container(
- alignment: Alignment.center,
- width: 81.w,
- height: 28.h,
- decoration: ShapeDecoration(
- color: const Color(0xFFE1E0E7),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(16.r),
- ),
- ),
- child: Obx(() {
- return Text(
- isCustom
- ? '${StringName.intimacy}${controller.currentCustomIntimacy}%'
- : '${StringName.intimacy}${controller.currentGeneralIntimacy}%',
- textAlign: TextAlign.right,
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 12.sp,
- fontWeight: FontWeight.w400,
- ),
- );
- }),
- ),
- ],
- ),
- SizedBox(height: 19.h),
- Builder(
- builder: (context) {
- return SliderTheme(
- data: SliderTheme.of(context).copyWith(
- trackShape: const GradientRectSliderTrackShape(),
- trackHeight: 8.h,
- thumbColor: Colors.white,
- thumbShape: RoundSliderThumbShape(enabledThumbRadius: 7.r),
- overlayShape: const RoundSliderOverlayShape(
- overlayRadius: 16,
- ),
- ),
- child: Obx(() {
- return Slider(
- value:
- isCustom
- ? controller.currentCustomIntimacy.toDouble()
- : controller.currentGeneralIntimacy.toDouble(),
- divisions: 100,
- min: 0,
- max: 100,
- onChanged: (value) {
- controller.updateIntimacy(value.toInt(), isCustom);
- },
- );
- }),
- );
- },
- ),
- ],
- ),
- );
- }
- // 键盘人设列表
- Widget _buildKeyboardCharacter({required bool isCustom}) {
- return Column(
- mainAxisAlignment: MainAxisAlignment.start,
- crossAxisAlignment: CrossAxisAlignment.start,
- children: [
- Padding(
- padding: EdgeInsets.only(left: 16.w, top: 24.h, bottom: 16.h),
- child: Text(
- StringName.keyboardCharacter,
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 14.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- Obx(() {
- return ReorderableWrap(
- runSpacing: 16.h,
- spacing: 4.w,
- runAlignment: WrapAlignment.start,
- alignment: WrapAlignment.start,
- needsLongPressDraggable: true,
- padding: EdgeInsets.symmetric(horizontal: 16.w),
- onReorder: (oldIndex, newIndex) {
- controller.onReorder(oldIndex, newIndex, isCustom);
- },
- onNoReorder: (int index) {},
- onReorderStarted: (int index) {},
- scrollPhysics: const BouncingScrollPhysics(),
- footer: [
- _buildFooterItem(
- image: Assets.images.iconKeyboardManagePlus.image(
- width: 18.w,
- height: 18.w,
- ),
- name: StringName.addCharacter,
- onTap: () {
- controller.clickAddCharacter(isCustom: isCustom);
- },
- ),
- _buildFooterItem(
- image: Assets.images.iconKeyboardManageCustom.image(
- width: 18.w,
- height: 18.w,
- ),
- name: StringName.customCharacter,
- onTap: () {
- controller.clickCustomCharacter();
- },
- ),
- ],
- children:
- isCustom
- ? controller.currentCustomKeyboardCharacterList
- .map(
- (e) => _buildKeyboardCharacterItem(
- e,
- isCustom: isCustom,
- ),
- )
- .toList()
- : controller.currentGeneralKeyboardCharacterList
- .map(
- (e) => _buildKeyboardCharacterItem(
- e,
- isCustom: isCustom,
- ),
- )
- .toList(),
- );
- }),
- ],
- );
- }
- Widget _buildKeyboardCharacterItem(
- CharacterInfo characterInfo, {
- required bool isCustom,
- }) {
- return SizedBox(
- width: (Get.width - 40.w) / 3,
- child: Stack(
- children: [
- Container(
- height: 44.h,
- margin: EdgeInsets.only(top: 4.h),
- decoration: ShapeDecoration(
- color: const Color(0xFFF5F4F9),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(8.r),
- ),
- ),
- alignment: Alignment.center,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Expanded(
- child: Text(
- '${characterInfo.emoji}${characterInfo.name}',
- style: TextStyle(
- color: Colors.black.withAlpha(204),
- fontSize: 14.sp,
- fontWeight: FontWeight.w400,
- ),
- textAlign: TextAlign.center,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- ),
- ),
- ],
- ),
- ),
- Positioned(
- right: 0,
- top: 0,
- child: GestureDetector(
- onTap: () {
- controller.clickRemoveCharacter(characterInfo, isCustom);
- },
- child: Assets.images.iconKeyboardManageX.image(
- width: 18.w,
- height: 18.w,
- ),
- ),
- ),
- ],
- ),
- );
- }
- // 添加人设按钮
- Widget _buildFooterItem({
- required Widget image,
- required String name,
- void Function()? onTap,
- }) {
- return GestureDetector(
- onTap: onTap,
- child: Container(
- margin: EdgeInsets.only(top: 4.h),
- child: DottedBorder(
- color: const Color(0xFFC9C2DB),
- // 虚线颜色
- strokeWidth: 1.0.w,
- // 线条宽度
- borderType: BorderType.Rect,
- // 圆角矩形
- radius: Radius.circular(8.r),
- // 圆角半径
- child: Container(
- width: 102.w,
- height: 38.h,
- alignment: Alignment.center,
- child: Row(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- image,
- Text(
- name,
- style: TextStyle(
- color: const Color(0xFFC9C2DB),
- fontSize: 14.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- ],
- ),
- ),
- ),
- ),
- );
- }
- // 保存按钮
- Widget _buildSaveButton({required bool isCustom}) {
- return Obx(() {
- bool hasChanges =
- isCustom
- ? (controller.customKeyboardCharacterListChanged ||
- controller.customIntimacyChanged)
- : (controller.generalKeyboardCharacterListChanged ||
- controller.generalIntimacyChanged.value);
- return GestureDetector(
- onTap: () {
- controller.clickSave(isCustom);
- },
- child: Container(
- width: double.infinity,
- margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
- height: 48.h,
- alignment: Alignment.center,
- decoration:
- hasChanges
- ? ShapeDecoration(
- gradient: LinearGradient(
- begin: Alignment(0.04, 0.21),
- end: Alignment(0.98, 0.76),
- colors: [
- const Color(0xFF7D46FC),
- const Color(0xFFBC87FF),
- ],
- ),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(50.r),
- ),
- shadows: [
- BoxShadow(
- color: Color(0x66BDA8C9),
- blurRadius: 10,
- offset: Offset(0, 4),
- spreadRadius: 0,
- ),
- ],
- )
- : ShapeDecoration(
- color: const Color(0x33121212),
- shape: RoundedRectangleBorder(
- borderRadius: BorderRadius.circular(29.50),
- ),
- ),
- child: Text(
- StringName.keyboardSave,
- textAlign: TextAlign.center,
- style: TextStyle(
- color: Colors.white,
- fontSize: 16.sp,
- fontWeight: FontWeight.w500,
- ),
- ),
- ),
- );
- });
- }
- }
|