From 454bad1ffed339b31361eef9c003b3363197c892 Mon Sep 17 00:00:00 2001 From: lowrt Date: Sat, 6 Dec 2025 15:46:56 +0800 Subject: [PATCH 1/3] fix: forecast_card --- lib/app/home/_widgets/forecast_card.dart | 114 +++++++++++++++-------- 1 file changed, 73 insertions(+), 41 deletions(-) diff --git a/lib/app/home/_widgets/forecast_card.dart b/lib/app/home/_widgets/forecast_card.dart index dffef45c4..4e43827b3 100644 --- a/lib/app/home/_widgets/forecast_card.dart +++ b/lib/app/home/_widgets/forecast_card.dart @@ -22,6 +22,8 @@ class _ForecastCardState extends State { final Map _pageKeys = {}; final Set _measuringPages = {}; List> _pages = []; + double maxWeatherWidth = 0; + List? _lastForecast; @override void dispose() { @@ -34,6 +36,37 @@ class _ForecastCardState extends State { try { final data = widget.forecast['forecast'] as List?; if (data == null || data.isEmpty) return const SizedBox.shrink(); + if (_lastForecast != data) { + _lastForecast = data; + + final List allWeatherTexts = []; + for (final item in data) { + final w = item['weather'] as String?; + if (w != null && w.isNotEmpty) allWeatherTexts.add(w); + } + + double longestWidth = 0; + for (final text in allWeatherTexts) { + final tp = TextPainter( + text: TextSpan( + text: text, + style: context.theme.textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + fontSize: 12, + ), + ), + maxLines: 1, + textDirection: TextDirection.ltr, + )..layout(minWidth: 0, maxWidth: double.infinity); + + longestWidth = max(longestWidth, tp.width); + } + + const iconWidth = 30; + const spacing = 8; + const popWidth = 55; + maxWeatherWidth = iconWidth + spacing + longestWidth + spacing + popWidth; + } double minTemp = double.infinity; double maxTemp = double.negativeInfinity; @@ -44,8 +77,8 @@ class _ForecastCardState extends State { } _pages = >[]; - for (int i = 0; i < data.length; i += 4) { - _pages.add(data.skip(i).take(4).toList()); + for (int i = 0; i < data.length; i += 6) { + _pages.add(data.skip(i).take(6).toList()); } final pages = _pages; @@ -102,7 +135,7 @@ class _ForecastCardState extends State { double height = 0; final pageData = pages[pageIndex]; for (int i = 0; i < pageData.length; i++) { - final globalIndex = pageIndex * 4 + i; + final globalIndex = pageIndex * 6 + i; final isExpanded = _expandedItems.contains(globalIndex); height += isExpanded ? 320 : 84; if (i < pageData.length - 1 && !isExpanded) height += 1; @@ -127,7 +160,7 @@ class _ForecastCardState extends State { setState(() { _currentPage = index; if (index < _pages.length) { - final currentPageStart = index * 4; + final currentPageStart = index * 6; final currentPageEnd = currentPageStart + _pages[index].length - 1; _expandedItems.removeWhere((expandedIndex) { return expandedIndex < currentPageStart || expandedIndex > currentPageEnd; @@ -136,6 +169,7 @@ class _ForecastCardState extends State { _measuredHeights.clear(); } } + _measuredHeights.removeWhere((key, value) => key != index); }); }, itemBuilder: (context, pageIndex) { @@ -168,7 +202,7 @@ class _ForecastCardState extends State { child: Column( mainAxisSize: MainAxisSize.min, children: pages[pageIndex].asMap().entries.map((entry) { - final globalIndex = pageIndex * 4 + entry.key; + final globalIndex = pageIndex * 6 + entry.key; return _buildForecastItem( context, entry.value as Map, @@ -232,7 +266,7 @@ class _ForecastCardState extends State { ..clear() ..add(index); } - final pageIndex = index ~/ 4; + final pageIndex = index ~/ 6; _measuredHeights.remove(pageIndex); }); }, @@ -262,7 +296,7 @@ class _ForecastCardState extends State { ), ), SizedBox( - width: 135, + width: maxWeatherWidth, child: Row( mainAxisSize: MainAxisSize.min, spacing: 4, @@ -276,45 +310,43 @@ class _ForecastCardState extends State { child: _getWeatherIcon(weather, context), ), if (weather.isNotEmpty) - Flexible( - child: Text( - weather, - style: context.theme.textTheme.bodySmall?.copyWith( - fontWeight: FontWeight.w500, - color: context.colors.onSurfaceVariant, - fontSize: 12, - ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - ), + Text( + weather, + style: context.theme.textTheme.bodySmall?.copyWith( + fontWeight: FontWeight.w500, + color: context.colors.onSurfaceVariant, + fontSize: 12, ), + maxLines: 1, + overflow: TextOverflow.visible, + ), if (pop > 0) - Container( - padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), - decoration: BoxDecoration( - color: Colors.indigo.withValues(alpha: 0.15), - borderRadius: BorderRadius.circular(4), - ), - child: Row( - mainAxisSize: MainAxisSize.min, - spacing: 2, - children: [ - Icon( - Symbols.rainy_rounded, - size: 13, + Container( + padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2), + decoration: BoxDecoration( + color: Colors.indigo.withValues(alpha: 0.15), + borderRadius: BorderRadius.circular(4), + ), + child: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Icon( + Symbols.rainy_rounded, + size: 13, + color: Colors.indigo, + ), + const SizedBox(width: 2), + Text( + '$pop%', + style: const TextStyle( + fontSize: 11, color: Colors.indigo, + fontWeight: FontWeight.w700, ), - Text( - '$pop%', - style: TextStyle( - fontSize: 11, - color: Colors.indigo, - fontWeight: FontWeight.w700, - ), - ), - ], - ), + ), + ], ), + ), ], ), ), From d95c3d08206589bc49f4ff793caabe8d091b8250 Mon Sep 17 00:00:00 2001 From: lowrt Date: Sat, 6 Dec 2025 15:47:20 +0800 Subject: [PATCH 2/3] build: 300103104 --- android/app/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 431db75ad..a58d5721e 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -49,7 +49,7 @@ android { applicationId 'com.exptech.dpip' minSdkVersion 26 targetSdkVersion 36 - versionCode 300103103 + versionCode 300103104 versionName flutterVersionName multiDexEnabled true resConfigs "en", "ko", "zh-rTW", "ja", "zh-rCN" From 291ea8c28dead5f42ffdc34074a12a4066e56944 Mon Sep 17 00:00:00 2001 From: lowrt Date: Sat, 6 Dec 2025 16:58:00 +0800 Subject: [PATCH 3/3] fix: TextPainter --- lib/app/home/_widgets/forecast_card.dart | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/app/home/_widgets/forecast_card.dart b/lib/app/home/_widgets/forecast_card.dart index 4e43827b3..334f44262 100644 --- a/lib/app/home/_widgets/forecast_card.dart +++ b/lib/app/home/_widgets/forecast_card.dart @@ -60,6 +60,7 @@ class _ForecastCardState extends State { )..layout(minWidth: 0, maxWidth: double.infinity); longestWidth = max(longestWidth, tp.width); + tp.dispose(); } const iconWidth = 30;