125 lines
3.6 KiB
Dart
125 lines
3.6 KiB
Dart
// Author: fruit.com.cn
|
|
|
|
import 'package:flutter/material.dart';
|
|
|
|
import '../../../core/theme/app_colors.dart';
|
|
import '../../../core/theme/app_dimens.dart';
|
|
import '../../../l10n/app_localizations.dart';
|
|
import '../recommend_types.dart';
|
|
|
|
const double _navHeight = 56;
|
|
const double _tabGap = 22;
|
|
const double _tabFont = 17;
|
|
const double _searchHitSize = 40;
|
|
const double _searchIconSize = 26;
|
|
|
|
class RecommendTopNav extends StatelessWidget {
|
|
const RecommendTopNav({
|
|
super.key,
|
|
required this.selected,
|
|
required this.onSelected,
|
|
required this.onSearch,
|
|
this.onVideo = false,
|
|
});
|
|
|
|
static const double height = _navHeight;
|
|
|
|
final RecommendInnerTab selected;
|
|
final ValueChanged<RecommendInnerTab> onSelected;
|
|
final VoidCallback onSearch;
|
|
final bool onVideo;
|
|
|
|
@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: Padding(
|
|
padding: const EdgeInsets.symmetric(
|
|
horizontal: AppDimens.feedPageHorizontal,
|
|
),
|
|
child: Stack(
|
|
alignment: Alignment.center,
|
|
children: [
|
|
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}'),
|
|
label: items[index].$2,
|
|
selected: selected == items[index].$1,
|
|
shadows: shadows,
|
|
onTap: () => onSelected(items[index].$1),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
Align(
|
|
alignment: Alignment.centerRight,
|
|
child: 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),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _tab({
|
|
required Key key,
|
|
required String label,
|
|
required bool selected,
|
|
required List<Shadow>? shadows,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return GestureDetector(
|
|
key: key,
|
|
behavior: HitTestBehavior.opaque,
|
|
onTap: onTap,
|
|
child: SizedBox(
|
|
height: height,
|
|
child: Center(
|
|
child: Text(
|
|
label,
|
|
maxLines: 1,
|
|
style: TextStyle(
|
|
color: selected
|
|
? AppColors.textPrimary
|
|
: AppColors.textTabInactive,
|
|
fontSize: _tabFont,
|
|
fontWeight: selected ? FontWeight.w700 : FontWeight.w400,
|
|
letterSpacing: 0,
|
|
shadows: shadows,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|