menu_list.dart 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import 'package:flutter/material.dart';
  2. import 'package:flutter_screenutil/flutter_screenutil.dart';
  3. import 'package:get/get.dart';
  4. import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
  5. import '../../../../config/translations/strings_enum.dart';
  6. import '../../../../utils/system_helper.dart';
  7. import '../../../constants/iconfont/iconfont.dart';
  8. import '../../../dialog/all_dialog.dart';
  9. import '../../../routes/app_pages.dart';
  10. /// 菜单项数据模型
  11. class MenuItem {
  12. final IconData icon;
  13. final String title;
  14. final Color iconColor;
  15. final VoidCallback? onTap;
  16. MenuItem({
  17. required this.icon,
  18. required this.title,
  19. required this.iconColor,
  20. this.onTap,
  21. });
  22. }
  23. /// 菜单列表组件
  24. class MenuList extends StatelessWidget {
  25. const MenuList({super.key});
  26. // 获取菜单项列表(最多6个)
  27. List<MenuItem> _getMenuItems() {
  28. return [
  29. MenuItem(
  30. icon: IconFont.icon19,
  31. title: Strings.moviesAndTV.tr,
  32. iconColor: const Color(0xFFFF3B30),
  33. onTap: () {
  34. // 处理点击事件
  35. print('Movies&TV tapped');
  36. Get.toNamed(Routes.MEDIALOCATION);
  37. },
  38. ),
  39. MenuItem(
  40. icon: IconFont.icon26,
  41. title: Strings.social.tr,
  42. iconColor: const Color(0xFF007AFF),
  43. onTap: () {
  44. print('Social tapped');
  45. SystemHelper.openTestPage();
  46. },
  47. ),
  48. MenuItem(
  49. icon: IconFont.icon28,
  50. title: Strings.support.tr,
  51. iconColor: const Color(0xFF34C759),
  52. onTap: () {
  53. print('Support tapped');
  54. AllDialog.showUpdate();
  55. },
  56. ),
  57. MenuItem(
  58. icon: IconFont.icon41,
  59. title: Strings.sport.tr,
  60. iconColor: const Color(0xFFFF9500),
  61. onTap: () {
  62. print('Sport tapped');
  63. },
  64. ),
  65. MenuItem(
  66. icon: IconFont.icon52,
  67. title: Strings.music.tr,
  68. iconColor: const Color(0xFF00C7BE),
  69. onTap: () {
  70. print('Music tapped');
  71. },
  72. ),
  73. MenuItem(
  74. icon: IconFont.icon53,
  75. title: Strings.game.tr,
  76. iconColor: const Color(0xFFAF52DE),
  77. onTap: () {
  78. print('Game tapped');
  79. },
  80. ),
  81. ];
  82. }
  83. @override
  84. Widget build(BuildContext context) {
  85. final menuItems = _getMenuItems();
  86. return GridView.builder(
  87. shrinkWrap: true,
  88. physics: const NeverScrollableScrollPhysics(),
  89. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  90. crossAxisCount: 3, // 每排3个
  91. crossAxisSpacing: 8.w, // 水平间距
  92. mainAxisSpacing: 8.w, // 垂直间距
  93. childAspectRatio: 3 / 2, // 宽高比
  94. ),
  95. itemCount: menuItems.length > 6 ? 6 : menuItems.length, // 最多6个
  96. itemBuilder: (context, index) {
  97. return _buildMenuItem(menuItems[index]);
  98. },
  99. );
  100. }
  101. /// 构建单个菜单项
  102. Widget _buildMenuItem(MenuItem item) {
  103. return GestureDetector(
  104. onTap: item.onTap,
  105. child: Container(
  106. decoration: BoxDecoration(
  107. color: Get.reactiveTheme.cardColor,
  108. borderRadius: BorderRadius.circular(10.r),
  109. ),
  110. child: Column(
  111. mainAxisAlignment: MainAxisAlignment.center,
  112. children: [
  113. // 图标
  114. Icon(item.icon, size: 20.w, color: item.iconColor),
  115. 4.verticalSpaceFromWidth,
  116. // 标题
  117. Text(
  118. item.title,
  119. textAlign: TextAlign.center,
  120. maxLines: 1,
  121. overflow: TextOverflow.ellipsis,
  122. style: TextStyle(
  123. fontSize: 13.sp,
  124. height: 1.4,
  125. color: Get.theme.hintColor,
  126. fontWeight: FontWeight.w500,
  127. ),
  128. ),
  129. ],
  130. ),
  131. ),
  132. );
  133. }
  134. }