fix(ui): 列表剧名统一两行省略,收藏卡去掉观看进度副标题

筛选、追剧收藏、新片、榜单、缓存与推荐上新等列表卡都按两行剧名预留高度,
超长标题显示省略号;收藏卡不再显示「看到第 N 集」,文字区高度同步收窄。
This commit is contained in:
Vicky authored and trae-solo-agent committed 2026-10-29 15:44:30 +08:00
1 parent 4dd37b2588
commit c311985601
9 files changed
+31 -48

No files matched your search

+5 -5
View File
@@ -150,8 +150,8 @@ abstract final class AppDimens {
static const double recommendSectionTitle = 17;
static const double recommendSectionSubtitle = 11;
static const double recommendSectionMore = 12;
// 封面 122*(4/3)≈163 + 间距6 + 两行标题39 + 间距6 + 标签13 ≈ 227。
static const double recommendRowHeight = 228;
// 封面 122*(4/3)≈163 + 间距6 + 两行标题≈42 + 间距6 + 标签≈13 ≈ 230,留 6 余量。
static const double recommendRowHeight = 236;
static const double recommendCardWidth = 122;
/// 首页热播榜。
@@ -189,9 +189,9 @@ abstract final class AppDimens {
static const double followingAddIconStroke = 1.5;
static const double followingGridGap = 6;
static const double followingGridRowGap = 12;
// 单行标题 16*1.3=20.8 + 间距 6+4 + 副标题行高约 18.6 ≈ 49.4,留 0.6 余量;
// 按 48 估算在副标题行高偏高的字体下会溢出 1~2px。
static const double followingCardTextExtent = 50;
/// 追剧网格卡文字区:间距 6 + 两行剧名 16*1.3*2=41.6 ≈ 48,留 4 余量。
static const double followingCardTextExtent = 52;
static const double followingSubtitleFont = 12;
static const double followingSubtitleGap = 4;
static const double followingProgressHeight = 2;
+1 -1
View File
@@ -374,7 +374,7 @@ class _LicenseTile extends StatelessWidget {
Expanded(
child: Text(
license.dramaTitle,
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.onSurface,
+3 -1
View File
@@ -23,7 +23,9 @@ const double _optionHorizontal = 5;
const double _optionVertical = 5;
const double _optionRunGap = 4;
const double _cardGap = 14;
const double _gridAspectRatio = 0.56;
/// 卡片比例:三列网格里要装下封面 + 两行剧名 + 元信息。
const double _gridAspectRatio = 0.53;
const double _groupFontSize = 13;
const double _labelFontSize = 12;
@@ -88,7 +88,7 @@ class FilterResultCard extends StatelessWidget {
Text(
drama.title,
key: Key('filter-title-${drama.id}'),
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.onSurface,
@@ -167,18 +167,10 @@ class FollowingFavoritesGrid extends StatelessWidget {
bool isEditing,
Set<String> picked,
) {
final l10n = AppLocalizations.of(context)!;
if (index == controller.cards.length) {
return FollowingAddCard(onTap: onGoHome);
}
final drama = controller.cards[index];
final record = history.recordForDrama(drama.id);
final episode = drama.episodes.isEmpty ? 1 : drama.episodes.first.number;
final watchedEpisode = record?.episodeNumber ?? 0;
final total = drama.episodeCount;
final subtitle = watchedEpisode > 0 && total > 0
? l10n.watchedEpisodeTotal(watchedEpisode, total)
: l10n.favoriteEpisodeProgress(episode, total);
return FollowingGridCard(
dramaId: drama.id,
title: drama.localizedTitle(Localizations.localeOf(context).languageCode),
@@ -186,10 +178,7 @@ class FollowingFavoritesGrid extends StatelessWidget {
viewCount: drama.viewCount,
editing: isEditing,
selected: isEditing ? picked.contains(drama.id) : null,
subtitle: subtitle,
// TODO(backend): Drama 增加 hasUpdate / latestEpisodeNumber / isFinished
// 字段后,在此传 updateBadge(l10n.hasUpdateBadge)、红色更新副标题
// (l10n.updatedToEpisode)或灰色完结副标题(l10n.finishedAllEpisodes)。
// TODO(backend): Drama 增加 hasUpdate 字段后,在此传 updateBadge。
onTap: () => _openOrToggle(context, drama.id, isEditing),
);
}
+1 -18
View File
@@ -19,21 +19,18 @@ class FollowingGridCard extends StatelessWidget {
required this.title,
required this.posterUrl,
required this.viewCount,
required this.subtitle,
required this.onTap,
this.progress,
this.editing = false,
this.selected,
this.onRemove,
this.updateBadge,
this.subtitleColor,
});
final String dramaId;
final String title;
final String posterUrl;
final int viewCount;
final String subtitle;
final VoidCallback onTap;
final double? progress;
final bool editing;
@@ -44,9 +41,6 @@ class FollowingGridCard extends StatelessWidget {
/// 待后端在 Drama 增加更新状态字段后由收藏网格传入。
final String? updateBadge;
/// 副标题颜色;更新中用强调红,完结用默认灰。
final Color? subtitleColor;
@override
Widget build(BuildContext context) {
return InkWell(
@@ -165,7 +159,7 @@ class FollowingGridCard extends StatelessWidget {
const SizedBox(height: AppDimens.cardCoverTitleGap),
Text(
title,
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: const TextStyle(
@@ -175,17 +169,6 @@ class FollowingGridCard extends StatelessWidget {
height: AppDimens.cardTitleLineHeight,
),
),
const SizedBox(height: AppDimens.followingSubtitleGap),
Text(
subtitle,
maxLines: 1,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.left,
style: TextStyle(
color: subtitleColor ?? AppColors.textTertiary,
fontSize: AppDimens.followingCardSubtitleFontNew,
),
),
],
),
);
@@ -22,7 +22,9 @@ const int _moreLimit = 12;
const int _filmHoles = 8;
const double _cardPadding = 8;
const double _cardWidth = 124;
const double _rowHeight = 204;
/// 横向卡片行高:封面 144 + 两行剧名 + 上映日期。
const double _rowHeight = 226;
const double _cardRadius = 12;
const double _loadMoreThreshold = 200;
@@ -173,9 +175,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
child: SizedBox(height: 14),
),
if (more.isNotEmpty) ...[
SliverToBoxAdapter(
child: _moreHeader(l10n),
),
SliverToBoxAdapter(child: _moreHeader(l10n)),
const SliverToBoxAdapter(
child: SizedBox(height: 10),
),
@@ -467,7 +467,7 @@ class _NewReleasesPageState extends State<NewReleasesPage> {
const SizedBox(height: 4),
Text(
drama.title,
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.onSurface,
+1 -1
View File
@@ -464,7 +464,7 @@ class _RankingRow extends StatelessWidget {
children: [
Text(
drama.title,
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textPrimary,
@@ -15,6 +15,12 @@ const double _cardCoverHeight = 157;
const double _cardGap = 9;
const double _cardRadius = 12;
/// 海报卡封面以下的高度:上间距 8 + 两行剧名 + 2 + 集数行 + 余量。
///
/// 横向列表和网格都要给一个有限的卡片高度,这里是唯一来源,
/// 两行剧名撑高时只改这一处,不会出现某个入口高度不够而溢出。
const double homePosterCardBodyExtent = 62;
/// 上新横滑卡板块。无板块标题,卡片左上角带「上新」角标。
/// 内层横向 ListView 会自行识别横向手势,不与外层纵向滚动冲突。
class HomeNewArrivalRow extends StatelessWidget {
@@ -32,8 +38,7 @@ class HomeNewArrivalRow extends StatelessWidget {
if (dramas.isEmpty) return const SizedBox.shrink();
return SizedBox(
key: const Key('home-new-arrival-row'),
height:
_cardCoverHeight + 8 + 20 + 2 + 16, // 封面 + 剧名行 + 集数行 + 余量
height: _cardCoverHeight + homePosterCardBodyExtent,
child: ListView.separated(
scrollDirection: Axis.horizontal,
padding: const EdgeInsets.symmetric(horizontal: _pageSide),
@@ -130,7 +135,7 @@ class HomePosterCard extends StatelessWidget {
const SizedBox(height: 8),
Text(
drama.localizedTitle(lang),
maxLines: 1,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
color: AppColors.textPrimary,
@@ -192,7 +197,11 @@ class HomeEditorPickBanner extends StatelessWidget {
gradient: LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [Color(0xE6000000), Color(0x4D000000), Color(0x1A000000)],
colors: [
Color(0xE6000000),
Color(0x4D000000),
Color(0x1A000000),
],
),
),
),