|
|
@@ -0,0 +1,375 @@
|
|
|
+import 'package:cached_network_image/cached_network_image.dart';
|
|
|
+import 'package:flutter/src/widgets/framework.dart';
|
|
|
+import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
|
+import 'package:keyboard/base/base_page.dart';
|
|
|
+import 'package:keyboard/module/profile/edit/profile_edit_controller.dart';
|
|
|
+import 'package:flutter/material.dart';
|
|
|
+import 'package:get/get.dart';
|
|
|
+
|
|
|
+import '../../../resource/assets.gen.dart';
|
|
|
+import '../../../resource/string.gen.dart';
|
|
|
+import '../../../router/app_pages.dart';
|
|
|
+import '../../../utils/styles.dart';
|
|
|
+import '../../../widget/gradient_rect_slider_track_shape.dart';
|
|
|
+
|
|
|
+class ProfileEditPage extends BasePage<ProfileEditController> {
|
|
|
+ const ProfileEditPage({super.key});
|
|
|
+
|
|
|
+ static start() {
|
|
|
+ Get.toNamed(RoutePath.profileEdit);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ bool immersive() {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ backgroundColor() {
|
|
|
+ return Color(0xFFF6F5FA);
|
|
|
+ }
|
|
|
+
|
|
|
+ @override
|
|
|
+ Widget buildBody(BuildContext context) {
|
|
|
+ return Stack(
|
|
|
+ children: [
|
|
|
+ Container(
|
|
|
+ child: Assets.images.bgCharacterCustomDetail.image(
|
|
|
+ width: double.infinity,
|
|
|
+ fit: BoxFit.fill,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ SafeArea(
|
|
|
+ child: Container(
|
|
|
+ color: Colors.transparent,
|
|
|
+ alignment: Alignment.topCenter,
|
|
|
+ child: Stack(
|
|
|
+ children: [
|
|
|
+ Column(
|
|
|
+ children: [
|
|
|
+ _buildTitle(),
|
|
|
+ SizedBox(height: 42.h),
|
|
|
+ Expanded(
|
|
|
+ child: Container(
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Color(0xFFF6F5FA),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.only(
|
|
|
+ topLeft: Radius.circular(20.r),
|
|
|
+ topRight: Radius.circular(20.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: SingleChildScrollView(
|
|
|
+ child: Column(
|
|
|
+ children: [
|
|
|
+ _buildNameCard(),
|
|
|
+ SizedBox(height: 20.h),
|
|
|
+ _buildIntimacySlider(),
|
|
|
+ SizedBox(height: 10.h),
|
|
|
+ _buildGenderCard(),
|
|
|
+
|
|
|
+ SizedBox(height: 10.h),
|
|
|
+ _buildBirthdayCard(),
|
|
|
+ SizedBox(height: 10.h),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ color: Color(0xFFF6F5FA),
|
|
|
+ child: _buildSaveButton(),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ Positioned(left: 16.w, top: 60.h, child: _buildAvatar()),
|
|
|
+ Positioned(left: 68.w, top: 112.h, child: _buildAvatarSwitch()),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ _buildTitle() {
|
|
|
+ return Container(
|
|
|
+ alignment: Alignment.centerLeft,
|
|
|
+ padding: EdgeInsets.only(top: 12.h, left: 16.w),
|
|
|
+ child: GestureDetector(
|
|
|
+ onTap: controller.clickBack,
|
|
|
+ child: Assets.images.iconMineBackArrow.image(width: 24.w, height: 24.w),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ _buildNameCard() {
|
|
|
+ return Container(
|
|
|
+ padding: EdgeInsets.only(left: 104.w, top: 14.h),
|
|
|
+ child: Row(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.end,
|
|
|
+ children: [
|
|
|
+ Text(
|
|
|
+ controller.currentCustomKeyboardInfo.name ?? '请输入昵称',
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ style: TextStyle(
|
|
|
+ color: Colors.black.withAlpha(204),
|
|
|
+ fontSize: 18.sp,
|
|
|
+ fontWeight: FontWeight.w500,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ Container(
|
|
|
+ child: Assets.images.iconCharacterCustomDetailEdit.image(
|
|
|
+ width: 20.r,
|
|
|
+ height: 20.r,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ _buildAvatar() {
|
|
|
+ return GestureDetector(
|
|
|
+ onTap: controller.nextAvatar,
|
|
|
+ child: Container(
|
|
|
+ width: 72.r,
|
|
|
+ height: 72.r,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ shape: OvalBorder(side: BorderSide(width: 2, color: Colors.white)),
|
|
|
+ ),
|
|
|
+ child:
|
|
|
+ controller.avatarUrl.isNotEmpty
|
|
|
+ ? CachedNetworkImage(
|
|
|
+ imageUrl: controller.avatarUrl,
|
|
|
+ width: 72.r,
|
|
|
+ height: 72.r,
|
|
|
+ )
|
|
|
+ : SizedBox(),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ _buildAvatarSwitch() {
|
|
|
+ return GestureDetector(
|
|
|
+ onTap: controller.nextAvatar,
|
|
|
+ child: SizedBox(
|
|
|
+ width: 22.r,
|
|
|
+ height: 22.r,
|
|
|
+ child: Assets.images.iconCharacterCustomDetailSwitch.image(
|
|
|
+ width: 22.r,
|
|
|
+ height: 22.r,
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 性别
|
|
|
+ Widget _buildGenderCard() {
|
|
|
+ return _buildListItem(
|
|
|
+ onTap: () {
|
|
|
+ debugPrint('点击了性别');
|
|
|
+ },
|
|
|
+ firstWidget: Text('性别', style: Styles.getTextStyleBlack204W400(14.sp)),
|
|
|
+ bottomWidget: Row(
|
|
|
+ children: [
|
|
|
+ Assets.images.iconCharacterCustomDetailMale.image(
|
|
|
+ width: 24.w,
|
|
|
+ height: 24.w,
|
|
|
+ ),
|
|
|
+ SizedBox(width: 6.w),
|
|
|
+ Text('男', style: Styles.getTextStyleBlack204W400(14.sp)),
|
|
|
+ Spacer(),
|
|
|
+ Assets.images.iconArrowRight.image(width: 24.w, height: 24.w),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildBirthdayCard() {
|
|
|
+ return _buildListItem(
|
|
|
+ onTap: () {
|
|
|
+ debugPrint('点击了生日');
|
|
|
+ },
|
|
|
+ firstWidget: Text('出生日期', style: Styles.getTextStyleBlack204W400(14.sp)),
|
|
|
+ bottomWidget: Row(
|
|
|
+ children: [
|
|
|
+ Text('1998-12-16', style: Styles.getTextStyleBlack204W400(14.sp)),
|
|
|
+ SizedBox(width: 12.w),
|
|
|
+ Text('22岁', style: Styles.getTextStyleBlack204W400(14.sp)),
|
|
|
+ Spacer(),
|
|
|
+ Assets.images.iconArrowRight.image(width: 24.w, height: 24.w),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildSaveButton() {
|
|
|
+ return GestureDetector(
|
|
|
+ onTap: () {
|
|
|
+ controller.clickSaveButton();
|
|
|
+ },
|
|
|
+ child: Container(
|
|
|
+ width: double.infinity,
|
|
|
+ margin: EdgeInsets.only(left: 16.w, right: 16.w, bottom: 16.h),
|
|
|
+ height: 48.h,
|
|
|
+ alignment: Alignment.center,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: const Color(0xFF7D46FC),
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(50.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Text(
|
|
|
+ StringName.profileEditSave,
|
|
|
+ textAlign: TextAlign.center,
|
|
|
+ style: Styles.getTextStyleWhiteW500(16.sp),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 列表项
|
|
|
+ Widget _buildListItem({
|
|
|
+ required Widget firstWidget,
|
|
|
+ required Widget bottomWidget,
|
|
|
+ VoidCallback? onTap,
|
|
|
+ }) {
|
|
|
+ return Container(
|
|
|
+ padding: EdgeInsets.only(
|
|
|
+ left: 12.w,
|
|
|
+ right: 12.w,
|
|
|
+ top: 14.h,
|
|
|
+ bottom: 14.h,
|
|
|
+ ),
|
|
|
+ margin: EdgeInsets.only(left: 16.w, right: 16.w),
|
|
|
+ width: double.infinity,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ color: Colors.white,
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ borderRadius: BorderRadius.circular(12.r),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ child: Column(
|
|
|
+ crossAxisAlignment: CrossAxisAlignment.start,
|
|
|
+ mainAxisAlignment: MainAxisAlignment.center,
|
|
|
+ children: [
|
|
|
+ firstWidget,
|
|
|
+ _buildDivider(),
|
|
|
+ GestureDetector(
|
|
|
+ behavior: HitTestBehavior.opaque,
|
|
|
+ onTap: onTap,
|
|
|
+ child: bottomWidget,
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ // 下划线
|
|
|
+ Widget _buildDivider() {
|
|
|
+ return Container(
|
|
|
+ margin: EdgeInsets.only(top: 8.h, bottom: 8.h),
|
|
|
+ width: 304.w,
|
|
|
+ decoration: ShapeDecoration(
|
|
|
+ shape: RoundedRectangleBorder(
|
|
|
+ side: BorderSide(
|
|
|
+ width: 1.r,
|
|
|
+ strokeAlign: BorderSide.strokeAlignCenter,
|
|
|
+ color: const Color(0xFFF5F4F9),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
+ Widget _buildIntimacySlider() {
|
|
|
+ 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.bgProfileEditIntimacy.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(
|
|
|
+ '${StringName.intimacy}${controller.currentCustomIntimacy}%',
|
|
|
+ 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: controller.currentCustomIntimacy.toDouble(),
|
|
|
+
|
|
|
+ divisions: 100,
|
|
|
+ min: 0,
|
|
|
+ max: 100,
|
|
|
+ onChanged: (value) {
|
|
|
+ controller.updateIntimacy(value.toInt());
|
|
|
+ },
|
|
|
+ );
|
|
|
+ }),
|
|
|
+ );
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ ],
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ }
|
|
|
+}
|