menu_list.dart 3.6 KB

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