Showing
1 changed file
with
152 additions
and
37 deletions
| @@ -2,9 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart'; | @@ -2,9 +2,11 @@ import 'package:cached_network_image/cached_network_image.dart'; | ||
| 2 | import 'package:doublefeel_flutter/app/models/input_dialog_meta_data.dart'; | 2 | import 'package:doublefeel_flutter/app/models/input_dialog_meta_data.dart'; |
| 3 | import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart'; | 3 | import 'package:doublefeel_flutter/app/modules/home/controllers/my_controller.dart'; |
| 4 | import 'package:doublefeel_flutter/app/modules/home/widgets/my/account_setting_view.dart'; | 4 | import 'package:doublefeel_flutter/app/modules/home/widgets/my/account_setting_view.dart'; |
| 5 | +import 'package:doublefeel_flutter/app/modules/watch_theme/models/watch_theme_models.dart'; | ||
| 5 | import 'package:doublefeel_flutter/app/routes/app_pages.dart'; | 6 | import 'package:doublefeel_flutter/app/routes/app_pages.dart'; |
| 6 | import 'package:doublefeel_flutter/app/utils/dialog_utils.dart'; | 7 | import 'package:doublefeel_flutter/app/utils/dialog_utils.dart'; |
| 7 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; | 8 | import 'package:doublefeel_flutter/core/theme/app_theme.dart'; |
| 9 | +import 'package:doublefeel_flutter/core/util/size_extensions.dart'; | ||
| 8 | import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; | 10 | import 'package:doublefeel_flutter/data/local/user_preferences_storage.dart'; |
| 9 | import 'package:doublefeel_flutter/data/models/local/user_preferences.dart'; | 11 | import 'package:doublefeel_flutter/data/models/local/user_preferences.dart'; |
| 10 | import 'package:doublefeel_flutter/data/models/user/user_models.dart'; | 12 | import 'package:doublefeel_flutter/data/models/user/user_models.dart'; |
| @@ -12,6 +14,8 @@ import 'package:flutter/foundation.dart'; | @@ -12,6 +14,8 @@ import 'package:flutter/foundation.dart'; | ||
| 12 | import 'package:flutter/material.dart'; | 14 | import 'package:flutter/material.dart'; |
| 13 | import 'package:get/get.dart'; | 15 | import 'package:get/get.dart'; |
| 14 | 16 | ||
| 17 | +import '../../../../../core/theme/app_colors.dart'; | ||
| 18 | + | ||
| 15 | class MyTab extends GetView<MyController> { | 19 | class MyTab extends GetView<MyController> { |
| 16 | const MyTab({super.key}); | 20 | const MyTab({super.key}); |
| 17 | 21 | ||
| @@ -46,7 +50,12 @@ class MyTab extends GetView<MyController> { | @@ -46,7 +50,12 @@ class MyTab extends GetView<MyController> { | ||
| 46 | const SizedBox(height: 28), | 50 | const SizedBox(height: 28), |
| 47 | _ProCard(vipInfo: vipInfo), | 51 | _ProCard(vipInfo: vipInfo), |
| 48 | const SizedBox(height: 12), | 52 | const SizedBox(height: 12), |
| 49 | - const _WatchThemeCard(), | 53 | + _WatchThemeCard( |
| 54 | + onTap: () => Get.toNamed( | ||
| 55 | + Routes.WATCH_THEME, | ||
| 56 | + arguments: {'isPremium': false, 'hasCustomThemes': false}, | ||
| 57 | + ), | ||
| 58 | + ), | ||
| 50 | const SizedBox(height: 12), | 59 | const SizedBox(height: 12), |
| 51 | _SettingsRow( | 60 | _SettingsRow( |
| 52 | title: '账号信息', | 61 | title: '账号信息', |
| @@ -73,6 +82,51 @@ class MyTab extends GetView<MyController> { | @@ -73,6 +82,51 @@ class MyTab extends GetView<MyController> { | ||
| 73 | ); | 82 | ); |
| 74 | } | 83 | } |
| 75 | } | 84 | } |
| 85 | +class _SettingsRow extends StatelessWidget { | ||
| 86 | + const _SettingsRow({required this.title, required this.onTap}); | ||
| 87 | + | ||
| 88 | + final String title; | ||
| 89 | + final VoidCallback onTap; | ||
| 90 | + | ||
| 91 | + @override | ||
| 92 | + Widget build(BuildContext context) { | ||
| 93 | + return GestureDetector( | ||
| 94 | + behavior: HitTestBehavior.opaque, | ||
| 95 | + onTap: onTap, | ||
| 96 | + child: Container( | ||
| 97 | + height: 56, | ||
| 98 | + padding: const EdgeInsets.symmetric(horizontal: 20), | ||
| 99 | + decoration: BoxDecoration( | ||
| 100 | + color: Colors.white, | ||
| 101 | + borderRadius: BorderRadius.circular(16), | ||
| 102 | + ), | ||
| 103 | + child: Row( | ||
| 104 | + children: [ | ||
| 105 | + Expanded( | ||
| 106 | + child: Text( | ||
| 107 | + title, | ||
| 108 | + maxLines: 1, | ||
| 109 | + overflow: TextOverflow.ellipsis, | ||
| 110 | + style: TextStyle( | ||
| 111 | + color: context.colors.textPrimary, | ||
| 112 | + fontSize: 14, | ||
| 113 | + fontWeight: FontWeight.w400, | ||
| 114 | + height: 1.4, | ||
| 115 | + ), | ||
| 116 | + ), | ||
| 117 | + ), | ||
| 118 | + Image.asset( | ||
| 119 | + 'assets/images/common/ic_more_gray.png', | ||
| 120 | + width: 16, | ||
| 121 | + height: 16, | ||
| 122 | + ), | ||
| 123 | + ], | ||
| 124 | + ), | ||
| 125 | + ), | ||
| 126 | + ); | ||
| 127 | + } | ||
| 128 | +} | ||
| 129 | + | ||
| 76 | 130 | ||
| 77 | class _ProfileHeader extends StatelessWidget { | 131 | class _ProfileHeader extends StatelessWidget { |
| 78 | const _ProfileHeader({required this.user}); | 132 | const _ProfileHeader({required this.user}); |
| @@ -303,59 +357,94 @@ class _ProCard extends StatelessWidget { | @@ -303,59 +357,94 @@ class _ProCard extends StatelessWidget { | ||
| 303 | } | 357 | } |
| 304 | } | 358 | } |
| 305 | 359 | ||
| 306 | -class _WatchThemeCard extends StatelessWidget { | ||
| 307 | - const _WatchThemeCard(); | 360 | +// class _WatchThemeCard extends StatelessWidget { |
| 361 | +// const _WatchThemeCard(); | ||
| 362 | +// | ||
| 363 | +// @override | ||
| 364 | +// Widget build(BuildContext context) { | ||
| 365 | +// return Container( | ||
| 366 | +// height: 145, | ||
| 367 | +// decoration: BoxDecoration( | ||
| 368 | +// color: Colors.white, | ||
| 369 | +// borderRadius: BorderRadius.circular(16), | ||
| 370 | +// ), | ||
| 371 | +// child: Image.asset('assets/images/my/ic_my_watch_theme.png'), | ||
| 372 | +// ); | ||
| 373 | +// } | ||
| 374 | +// } | ||
| 308 | 375 | ||
| 309 | - @override | ||
| 310 | - Widget build(BuildContext context) { | ||
| 311 | - return Container( | ||
| 312 | - height: 145, | ||
| 313 | - decoration: BoxDecoration( | ||
| 314 | - color: Colors.white, | ||
| 315 | - borderRadius: BorderRadius.circular(16), | ||
| 316 | - ), | ||
| 317 | - child: Image.asset('assets/images/my/ic_my_watch_theme.png'), | ||
| 318 | - ); | ||
| 319 | - } | ||
| 320 | -} | ||
| 321 | - | ||
| 322 | -class _SettingsRow extends StatelessWidget { | ||
| 323 | - const _SettingsRow({required this.title, required this.onTap}); | 376 | +class _WatchThemeCard extends StatelessWidget { |
| 377 | + const _WatchThemeCard({required this.onTap}); | ||
| 324 | 378 | ||
| 325 | - final String title; | ||
| 326 | final VoidCallback onTap; | 379 | final VoidCallback onTap; |
| 327 | 380 | ||
| 381 | + final double _itemSize = 64; | ||
| 382 | + final double _overlap = 8; | ||
| 383 | + | ||
| 328 | @override | 384 | @override |
| 329 | Widget build(BuildContext context) { | 385 | Widget build(BuildContext context) { |
| 330 | return GestureDetector( | 386 | return GestureDetector( |
| 331 | behavior: HitTestBehavior.opaque, | 387 | behavior: HitTestBehavior.opaque, |
| 332 | onTap: onTap, | 388 | onTap: onTap, |
| 333 | child: Container( | 389 | child: Container( |
| 334 | - height: 56, | ||
| 335 | - padding: const EdgeInsets.symmetric(horizontal: 20), | 390 | + padding: EdgeInsets.fromLTRB(20.dp, 20.dp, 20.dp, 18.dp), |
| 336 | decoration: BoxDecoration( | 391 | decoration: BoxDecoration( |
| 337 | color: Colors.white, | 392 | color: Colors.white, |
| 338 | - borderRadius: BorderRadius.circular(16), | 393 | + borderRadius: BorderRadius.circular(16.dp), |
| 339 | ), | 394 | ), |
| 340 | - child: Row( | 395 | + child: Column( |
| 396 | + crossAxisAlignment: CrossAxisAlignment.start, | ||
| 341 | children: [ | 397 | children: [ |
| 342 | - Expanded( | ||
| 343 | - child: Text( | ||
| 344 | - title, | ||
| 345 | - maxLines: 1, | ||
| 346 | - overflow: TextOverflow.ellipsis, | ||
| 347 | - style: TextStyle( | ||
| 348 | - color: context.colors.textPrimary, | ||
| 349 | - fontSize: 14, | ||
| 350 | - fontWeight: FontWeight.w400, | ||
| 351 | - height: 1.4, | 398 | + Row( |
| 399 | + children: [ | ||
| 400 | + Text( | ||
| 401 | + 'Watch主题', | ||
| 402 | + style: TextStyle( | ||
| 403 | + color: AppColors.textPrimary, | ||
| 404 | + fontSize: 16.dp, | ||
| 405 | + fontWeight: FontWeight.w600, | ||
| 406 | + height: 1.25, | ||
| 407 | + ), | ||
| 408 | + ), | ||
| 409 | + const Spacer(), | ||
| 410 | + Icon( | ||
| 411 | + Icons.chevron_right, | ||
| 412 | + color: AppColors.textTertiary, | ||
| 413 | + size: 20.dp, | ||
| 352 | ), | 414 | ), |
| 415 | + ], | ||
| 416 | + ), | ||
| 417 | + SizedBox(height: 17.dp), | ||
| 418 | + SizedBox( | ||
| 419 | + height: _itemSize, | ||
| 420 | + child: ListView.builder( | ||
| 421 | + scrollDirection: Axis.horizontal, | ||
| 422 | + clipBehavior: Clip.none, | ||
| 423 | + itemCount: officialThemes.length, | ||
| 424 | + itemBuilder: (context, index) { | ||
| 425 | + return Transform.translate( | ||
| 426 | + offset: Offset(index == 0 ? 0 : -_overlap * index, 0), | ||
| 427 | + child: _ThemeBubble( | ||
| 428 | + size: _itemSize, | ||
| 429 | + assetPath: officialThemes[index] | ||
| 430 | + .infoList | ||
| 431 | + .firstOrNull | ||
| 432 | + ?.assetPath ?? | ||
| 433 | + '', | ||
| 434 | + )); | ||
| 435 | + }, | ||
| 436 | + | ||
| 353 | ), | 437 | ), |
| 354 | ), | 438 | ), |
| 355 | - Image.asset( | ||
| 356 | - 'assets/images/common/ic_more_gray.png', | ||
| 357 | - width: 16, | ||
| 358 | - height: 16, | 439 | + SizedBox(height: 10.dp), |
| 440 | + Text( | ||
| 441 | + '支持自定义创作主题哦~', | ||
| 442 | + style: TextStyle( | ||
| 443 | + color: AppColors.primary, | ||
| 444 | + fontSize: 12.dp, | ||
| 445 | + fontWeight: FontWeight.w500, | ||
| 446 | + height: 1.25, | ||
| 447 | + ), | ||
| 359 | ), | 448 | ), |
| 360 | ], | 449 | ], |
| 361 | ), | 450 | ), |
| @@ -363,3 +452,29 @@ class _SettingsRow extends StatelessWidget { | @@ -363,3 +452,29 @@ class _SettingsRow extends StatelessWidget { | ||
| 363 | ); | 452 | ); |
| 364 | } | 453 | } |
| 365 | } | 454 | } |
| 455 | +class _ThemeBubble extends StatelessWidget { | ||
| 456 | + const _ThemeBubble({required this.size, required this.assetPath}); | ||
| 457 | + | ||
| 458 | + final double size; | ||
| 459 | + final String assetPath; | ||
| 460 | + | ||
| 461 | + @override | ||
| 462 | + Widget build(BuildContext context) { | ||
| 463 | + return Container( | ||
| 464 | + width: size, | ||
| 465 | + height: size, | ||
| 466 | + decoration: BoxDecoration( | ||
| 467 | + color: const Color(0xFFEDE8FF), | ||
| 468 | + shape: BoxShape.circle, | ||
| 469 | + border: Border.all(color: Colors.white, width: 4), | ||
| 470 | + ), | ||
| 471 | + alignment: Alignment.center, | ||
| 472 | + child: Image.asset( | ||
| 473 | + assetPath, | ||
| 474 | + width: 36, | ||
| 475 | + height: 36, | ||
| 476 | + fit: BoxFit.fill, | ||
| 477 | + ), | ||
| 478 | + ); | ||
| 479 | + } | ||
| 480 | +} |
-
Please register or login to post a comment