menu_list.dart 3.5 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 '../../../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. padding: EdgeInsets.symmetric(vertical: 15.w),
  85. gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
  86. crossAxisCount: 3, // 每排3个
  87. crossAxisSpacing: 8.w, // 水平间距
  88. mainAxisSpacing: 8.w, // 垂直间距
  89. childAspectRatio: 4 / 3, // 宽高比
  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. }