fix(home): 调整封面播放量位置
This commit is contained in:
1 parent
e11f55777e
commit
972e542e5c
10 files changed
+179
-147
No files matched your search
@@ -159,6 +159,8 @@ abstract final class AppColors {
|
||||
|
||||
/// 播放器控件胶囊与圆形底色。
|
||||
static const playerOverlayPill = Color(0xB3000000);
|
||||
static const cardBottomScrimStart = Color(0x00000000);
|
||||
static const cardBottomScrimEnd = Color(0x40000000);
|
||||
|
||||
/// 进度条未激活轨道。
|
||||
static const inactiveTrack = Color(0x24FFFFFF);
|
||||
|
||||
@@ -89,6 +89,8 @@ abstract final class AppDimens {
|
||||
static const double cardViewsIcon = 11;
|
||||
static const double cardPlayCountFont = 12;
|
||||
static const double cardPlayCountGap = 2;
|
||||
static const double cardPlayCountBottom = 6;
|
||||
static const double cardPlayCountScrimHeight = 32;
|
||||
static const double cardGenreRibbonHeight = 20;
|
||||
static const double cardGenreRibbonRadius = 10;
|
||||
static const double cardGenreRibbonLeftInset = 8;
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
// Author: fruit.com.cn
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../formatting/count_format.dart';
|
||||
import '../theme/app_colors.dart';
|
||||
import '../theme/app_dimens.dart';
|
||||
|
||||
class CoverPlayCount extends StatelessWidget {
|
||||
const CoverPlayCount({super.key, required this.count});
|
||||
|
||||
final int count;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.auto_awesome_rounded,
|
||||
color: AppColors.textPrimary,
|
||||
size: AppDimens.cardViewsIcon,
|
||||
),
|
||||
const SizedBox(width: AppDimens.cardPlayCountGap),
|
||||
Text(
|
||||
formatPlayCount(count),
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardPlayCountFont,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CoverBottomScrim extends StatelessWidget {
|
||||
const CoverBottomScrim({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return const SizedBox(
|
||||
height: AppDimens.cardPlayCountScrimHeight,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
gradient: LinearGradient(
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
colors: [
|
||||
AppColors.cardBottomScrimStart,
|
||||
AppColors.cardBottomScrimEnd,
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../core/formatting/count_format.dart';
|
||||
import '../../core/theme/app_colors.dart';
|
||||
import '../../core/theme/app_dimens.dart';
|
||||
import '../../core/widgets/cover_play_count.dart';
|
||||
import '../../core/widgets/remote_image.dart';
|
||||
|
||||
class FollowingGridCard extends StatelessWidget {
|
||||
@@ -80,31 +80,35 @@ class FollowingGridCard extends StatelessWidget {
|
||||
),
|
||||
),
|
||||
),
|
||||
const Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: CoverBottomScrim(),
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: AppDimens.cardPlayCountBottom,
|
||||
child: CoverPlayCount(
|
||||
key: Key('following-views-$dramaId'),
|
||||
count: viewCount,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDimens.cardCoverTitleGap),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppDimens.spaceXs),
|
||||
_views(),
|
||||
],
|
||||
Text(
|
||||
title,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
if (tags.isNotEmpty) ...[
|
||||
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||
@@ -140,30 +144,6 @@ class FollowingGridCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _views() {
|
||||
return Row(
|
||||
key: Key('following-views-$dramaId'),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.auto_awesome_rounded,
|
||||
color: AppColors.textPrimary,
|
||||
size: AppDimens.cardViewsIcon,
|
||||
),
|
||||
const SizedBox(width: AppDimens.cardPlayCountGap),
|
||||
Text(
|
||||
formatPlayCount(viewCount),
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardPlayCountFont,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _tags() {
|
||||
final visible = tags.take(3).toList(growable: false);
|
||||
return Text(
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/formatting/count_format.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/cover_play_count.dart';
|
||||
import '../../../core/widgets/drama_cover_badge_ribbon.dart';
|
||||
import '../../../core/widgets/remote_image.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
@@ -50,28 +50,18 @@ class HomeFeedCard extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
drama.title,
|
||||
key: Key('home-feed-title-${drama.id}'),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
color: AppColors.navSelected,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppDimens.spaceXs),
|
||||
_views(),
|
||||
],
|
||||
Text(
|
||||
drama.title,
|
||||
key: Key('home-feed-title-${drama.id}'),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
textAlign: TextAlign.left,
|
||||
style: const TextStyle(
|
||||
color: AppColors.navSelected,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||
_tags(),
|
||||
@@ -112,6 +102,20 @@ class HomeFeedCard extends StatelessWidget {
|
||||
keyPrefix: '${drama.id}-${badge.name}',
|
||||
),
|
||||
),
|
||||
const Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: CoverBottomScrim(),
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: AppDimens.cardPlayCountBottom,
|
||||
child: CoverPlayCount(
|
||||
key: Key('home-feed-views-${drama.id}'),
|
||||
count: drama.viewCount,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -145,31 +149,6 @@ class HomeFeedCard extends StatelessWidget {
|
||||
};
|
||||
}
|
||||
|
||||
Widget _views() {
|
||||
return Row(
|
||||
key: Key('home-feed-views-${drama.id}'),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.auto_awesome_rounded,
|
||||
size: AppDimens.cardViewsIcon,
|
||||
color: AppColors.navSelected,
|
||||
),
|
||||
const SizedBox(width: AppDimens.cardPlayCountGap),
|
||||
Text(
|
||||
formatPlayCount(drama.viewCount),
|
||||
style: const TextStyle(
|
||||
color: AppColors.navSelected,
|
||||
fontSize: AppDimens.cardPlayCountFont,
|
||||
fontWeight: FontWeight.w400,
|
||||
letterSpacing: 0,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget _tags() {
|
||||
final tags = _cardTags();
|
||||
if (tags.isEmpty) return const SizedBox.shrink();
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../core/data/models/drama.dart';
|
||||
import '../../../core/formatting/count_format.dart';
|
||||
import '../../../core/theme/app_colors.dart';
|
||||
import '../../../core/theme/app_dimens.dart';
|
||||
import '../../../core/widgets/cover_play_count.dart';
|
||||
import '../../../core/widgets/drama_cover_badge_ribbon.dart';
|
||||
import '../../../core/widgets/remote_image.dart';
|
||||
import '../../../l10n/app_localizations.dart';
|
||||
@@ -62,32 +62,36 @@ class RecommendSectionCard extends StatelessWidget {
|
||||
keyPrefix: '$sectionKey-${drama.id}-hot',
|
||||
),
|
||||
),
|
||||
const Positioned(
|
||||
left: 0,
|
||||
right: 0,
|
||||
bottom: 0,
|
||||
child: CoverBottomScrim(),
|
||||
),
|
||||
Positioned(
|
||||
right: 0,
|
||||
bottom: AppDimens.cardPlayCountBottom,
|
||||
child: CoverPlayCount(
|
||||
key: Key('recommend-views-$sectionKey-${drama.id}'),
|
||||
count: drama.viewCount,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDimens.cardCoverTitleGap),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
Expanded(
|
||||
child: Text(
|
||||
drama.title,
|
||||
key: Key('recommend-title-$sectionKey-${drama.id}'),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: AppDimens.spaceXs),
|
||||
_views(),
|
||||
],
|
||||
Text(
|
||||
drama.title,
|
||||
key: Key('recommend-title-$sectionKey-${drama.id}'),
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardTitleFont,
|
||||
fontWeight: FontWeight.w500,
|
||||
height: AppDimens.cardTitleLineHeight,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: AppDimens.cardTitleTagGap),
|
||||
_tags(),
|
||||
@@ -97,30 +101,6 @@ class RecommendSectionCard extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Widget _views() {
|
||||
return Row(
|
||||
key: Key('recommend-views-$sectionKey-${drama.id}'),
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.auto_awesome_rounded,
|
||||
color: AppColors.textPrimary,
|
||||
size: AppDimens.cardViewsIcon,
|
||||
),
|
||||
const SizedBox(width: AppDimens.cardPlayCountGap),
|
||||
Text(
|
||||
formatPlayCount(drama.viewCount),
|
||||
style: const TextStyle(
|
||||
color: AppColors.textPrimary,
|
||||
fontSize: AppDimens.cardPlayCountFont,
|
||||
fontWeight: FontWeight.w400,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
List<String> _cardTags() {
|
||||
final seen = <String>{};
|
||||
return [drama.genre, drama.category]
|
||||
|
||||
Reference in new issue
Block a user