fix(ui): 列表剧名统一两行省略,收藏卡去掉观看进度副标题
筛选、追剧收藏、新片、榜单、缓存与推荐上新等列表卡都按两行剧名预留高度, 超长标题显示省略号;收藏卡不再显示「看到第 N 集」,文字区高度同步收窄。
This commit is contained in:
1 parent
4dd37b2588
commit
c311985601
9 files changed
+31
-48
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Reference in new issue
Block a user