menu_list.dart 3.5 KB

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