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