// Author: fruit.com.cn import 'package:flutter/material.dart'; import '../../../core/theme/app_colors.dart'; import '../../../l10n/app_localizations.dart'; import '../recommend_types.dart'; const double _navHeight = 56; const double _tabGap = 20; const double _tabFont = 17; const double _searchHitSize = 40; const double _searchIconSize = 26; const double _giftIconSize = 30; const double _underlineWidth = 26; const double _underlineHeight = 3; class RecommendTopNav extends StatelessWidget { const RecommendTopNav({ super.key, required this.selected, required this.onSelected, required this.onSearch, this.onVideo = false, this.onGift, }); static const double height = _navHeight; final RecommendInnerTab selected; final ValueChanged onSelected; final VoidCallback onSearch; final bool onVideo; /// 右上角金色礼物盒(钱包入口);为空时不显示。 final VoidCallback? onGift; @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; final items = [ (RecommendInnerTab.feed, l10n.recommendTopTab, 'recommend'), (RecommendInnerTab.playlists, l10n.playlistTopTab, 'playlist'), (RecommendInnerTab.allDramas, l10n.allDramasTopTab, 'all'), ]; final shadows = onVideo ? const [Shadow(color: AppColors.mediaBlack, blurRadius: 6)] : null; return SizedBox( key: const Key('recommend-top-nav'), height: height, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Expanded( child: SingleChildScrollView( scrollDirection: Axis.horizontal, padding: const EdgeInsets.only(left: 20, right: 8), child: Row( mainAxisSize: MainAxisSize.min, children: [ for (var index = 0; index < items.length; index++) ...[ if (index > 0) const SizedBox(width: _tabGap), _tab( key: Key('recommend-tab-${items[index].$3}'), code: items[index].$3, label: items[index].$2, selected: selected == items[index].$1, shadows: shadows, onTap: () => onSelected(items[index].$1), ), ], ], ), ), ), SizedBox.square( dimension: _searchHitSize, child: IconButton( key: const Key('recommend-search'), tooltip: l10n.search, onPressed: onSearch, padding: EdgeInsets.zero, constraints: const BoxConstraints.tightFor( width: _searchHitSize, height: _searchHitSize, ), iconSize: _searchIconSize, color: AppColors.textPrimary, icon: const Icon(Icons.search_rounded), ), ), if (onGift != null) SizedBox.square( dimension: _searchHitSize, child: IconButton( key: const Key('recommend-gift'), tooltip: l10n.wallet, onPressed: onGift, padding: EdgeInsets.zero, constraints: const BoxConstraints.tightFor( width: _searchHitSize, height: _searchHitSize, ), iconSize: _giftIconSize, icon: Image.asset( 'assets/icon/gift.png', width: _giftIconSize, height: _giftIconSize, fit: BoxFit.contain, ), ), ), const SizedBox(width: 8), ], ), ); } Widget _tab({ required Key key, required String code, required String label, required bool selected, required List? shadows, required VoidCallback onTap, }) { return GestureDetector( key: key, behavior: HitTestBehavior.opaque, onTap: onTap, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 补偿文字下方的 4pt 间距 + 3pt 下划线,让文字视觉中心与右侧图标对齐。 const SizedBox(height: 4 + _underlineHeight), Text( label, maxLines: 1, style: TextStyle( color: AppColors.textPrimary, fontSize: _tabFont, fontWeight: selected ? FontWeight.w700 : FontWeight.w400, letterSpacing: 0, shadows: shadows, ), ), const SizedBox(height: 4), Container( key: Key('recommend-tab-$code-underline'), width: _underlineWidth, height: _underlineHeight, decoration: BoxDecoration( color: selected ? AppColors.brandRed : AppColors.transparent, borderRadius: BorderRadius.circular(_underlineHeight / 2), ), ), ], ), ); } }