| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193 |
- import 'package:flutter/material.dart';
- import 'package:flutter_screenutil/flutter_screenutil.dart';
- import 'package:get/get.dart';
- import 'package:nomo/config/theme/theme_extensions/theme_extension.dart';
- import '../../../../config/translations/strings_enum.dart';
- import '../../../../utils/system_helper.dart';
- import '../../../constants/iconfont/iconfont.dart';
- import '../../../dialog/all_dialog.dart';
- import '../../../routes/app_pages.dart';
- /// 菜单项数据模型
- class MenuItem {
- final IconData icon;
- final String title;
- final Color iconColor;
- final VoidCallback? onTap;
- MenuItem({
- required this.icon,
- required this.title,
- required this.iconColor,
- this.onTap,
- });
- }
- /// 菜单列表组件
- /// 支持放在 SliverFillRemaining 中
- /// 排列规则:
- /// - 6个:2排,每排3个
- /// - 5个:2排,第一排3个,第二排2个
- /// - 4个:2排,每排2个
- /// - 3个:1排,每排3个
- /// - 2个:1排,每排2个
- /// - 1个:1排,占满
- class MenuList extends StatelessWidget {
- const MenuList({super.key});
- // 获取菜单项列表(最多6个)
- List<MenuItem> _getMenuItems() {
- return [
- MenuItem(
- icon: IconFont.icon19,
- title: Strings.moviesAndTV.tr,
- iconColor: const Color(0xFFFF3B30),
- onTap: () {
- print('Movies&TV tapped');
- Get.toNamed(Routes.MEDIALOCATION);
- },
- ),
- MenuItem(
- icon: IconFont.icon26,
- title: Strings.social.tr,
- iconColor: const Color(0xFF007AFF),
- onTap: () {
- print('Social tapped');
- SystemHelper.openTestPage();
- },
- ),
- MenuItem(
- icon: IconFont.icon28,
- title: Strings.support.tr,
- iconColor: const Color(0xFF34C759),
- onTap: () {
- print('Support tapped');
- AllDialog.showUpdate(hasForceUpdate: true);
- },
- ),
- MenuItem(
- icon: IconFont.icon41,
- title: Strings.sport.tr,
- iconColor: const Color(0xFFFF9500),
- onTap: () {
- print('Sport tapped');
- },
- ),
- MenuItem(
- icon: IconFont.icon52,
- title: Strings.music.tr,
- iconColor: const Color(0xFF00C7BE),
- onTap: () {
- print('Music tapped');
- },
- ),
- MenuItem(
- icon: IconFont.icon53,
- title: Strings.game.tr,
- iconColor: const Color(0xFFAF52DE),
- onTap: () {
- print('Game tapped');
- },
- ),
- ];
- }
- /// 根据数量计算每排的布局
- /// 返回一个二维列表,每个子列表表示一排的菜单项
- List<List<MenuItem>> _calculateLayout(List<MenuItem> items) {
- final count = items.length.clamp(0, 6);
- if (count == 0) return [];
- switch (count) {
- case 1:
- // 1个:1排占满
- return [items.sublist(0, 1)];
- case 2:
- // 2个:1排,每排2个
- return [items.sublist(0, 2)];
- case 3:
- // 3个:1排,每排3个
- return [items.sublist(0, 3)];
- case 4:
- // 4个:2排,每排2个
- return [items.sublist(0, 2), items.sublist(2, 4)];
- case 5:
- // 5个:2排,第一排3个,第二排2个
- return [items.sublist(0, 3), items.sublist(3, 5)];
- case 6:
- default:
- // 6个:2排,每排3个
- return [items.sublist(0, 3), items.sublist(3, 6)];
- }
- }
- @override
- Widget build(BuildContext context) {
- final menuItems = _getMenuItems();
- final layout = _calculateLayout(menuItems);
- return Column(
- mainAxisSize: MainAxisSize.min,
- children: layout.asMap().entries.map((entry) {
- final rowIndex = entry.key;
- final rowItems = entry.value;
- return Padding(
- padding: EdgeInsets.only(top: rowIndex > 0 ? 8.w : 0),
- child: _buildRow(rowItems),
- );
- }).toList(),
- );
- }
- /// 构建一排菜单项
- Widget _buildRow(List<MenuItem> items) {
- return Row(
- children: items.asMap().entries.map((entry) {
- final index = entry.key;
- final item = entry.value;
- return Expanded(
- child: Padding(
- padding: EdgeInsets.only(left: index > 0 ? 8.w : 0),
- child: _buildMenuItem(item),
- ),
- );
- }).toList(),
- );
- }
- /// 构建单个菜单项
- Widget _buildMenuItem(MenuItem item) {
- return GestureDetector(
- onTap: item.onTap,
- child: Container(
- height: 56.w,
- decoration: BoxDecoration(
- color: Get.reactiveTheme.cardColor,
- borderRadius: BorderRadius.circular(10.r),
- ),
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- // 图标
- Icon(item.icon, size: 20.w, color: item.iconColor),
- 4.verticalSpaceFromWidth,
- // 标题
- Text(
- item.title,
- textAlign: TextAlign.center,
- maxLines: 1,
- overflow: TextOverflow.ellipsis,
- style: TextStyle(
- fontSize: 13.sp,
- height: 1.4,
- color: Get.theme.hintColor,
- fontWeight: FontWeight.w500,
- ),
- ),
- ],
- ),
- ),
- );
- }
- }
|