Commit 8d5a6c657725cc0b815b3364d18c97a5bba5977f

Authored by 常守达
1 parent ee15cd75

fix(today):说明弹窗

import 'package:doublefeel_flutter/app/modules/home/widgets/today/realtime_stress_explanation_bottom_sheet.dart';
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
... ... @@ -279,7 +280,9 @@ class _FaqLink extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => showTodayFaqBottomSheet(),
onTap: () => text == l10n.todayFaqLinkHrvRealtimeUpdate
? showRealtimeStressExplanationBottomSheet(Get.context!)
: showTodayFaqBottomSheet(text: text),
child: Padding(
padding: const EdgeInsets.only(bottom: 14),
child: Text(
... ...
import 'package:doublefeel_flutter/app/modules/home/widgets/today/hrv_principle_explanation_bottom_sheet.dart';
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
... ... @@ -293,7 +294,6 @@ class _FaqLinksCard extends StatelessWidget {
title: l10n.todayFaqSectionTitle,
children: [
_FaqLink(l10n.todayFaqLinkNoData),
_FaqLink(l10n.todayFaqLinkHrvRealtimeUpdate),
_FaqLink(l10n.todayFaqLinkWatchNoStatusNotification),
_FaqLink(l10n.todayFaqLinkWatchFaceDataDelay),
_FaqLink(l10n.todayFaqLinkWatchFaceBlackScreen),
... ... @@ -311,7 +311,9 @@ class _FaqLink extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => showTodayFaqBottomSheet(),
onTap: () => text == l10n.todayFaqLinkHrvRealtimeUpdate
? showRealtimeStressExplanationBottomSheet(Get.context!)
: showTodayFaqBottomSheet(text: text),
child: Padding(
padding: const EdgeInsets.only(bottom: 14),
child: Text(
... ...
import 'package:doublefeel_flutter/app/modules/home/widgets/today/hrv_principle_explanation_bottom_sheet.dart';
import 'package:doublefeel_flutter/app/modules/home/widgets/today/realtime_stress_explanation_bottom_sheet.dart';
import 'package:doublefeel_flutter/core/theme/app_theme.dart';
import 'package:doublefeel_flutter/l10n/l10n_extensions.dart';
import 'package:flutter/material.dart';
... ... @@ -312,7 +314,9 @@ class _FaqLink extends StatelessWidget {
Widget build(BuildContext context) {
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: () => showTodayFaqBottomSheet(),
onTap: () => text == l10n.todayFaqLinkHrvRealtimeUpdate
? showRealtimeStressExplanationBottomSheet(Get.context!)
: showTodayFaqBottomSheet(text: text),
child: Padding(
padding: const EdgeInsets.only(bottom: 14),
child: Text(
... ...
... ... @@ -5,7 +5,7 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
void showTodayFaqBottomSheet() {
void showTodayFaqBottomSheet({String? text}) {
final view = WidgetsBinding.instance.platformDispatcher.views.first;
final devicePixelRatio = view.devicePixelRatio;
final screenHeight = view.physicalSize.height / devicePixelRatio;
... ... @@ -20,6 +20,7 @@ void showTodayFaqBottomSheet() {
builder: (context, scrollController) {
return TodayFaqBottomSheet(
scrollController: scrollController,
scrollToText: text,
);
},
),
... ... @@ -30,13 +31,78 @@ void showTodayFaqBottomSheet() {
);
}
class TodayFaqBottomSheet extends StatelessWidget {
class TodayFaqBottomSheet extends StatefulWidget {
const TodayFaqBottomSheet({
super.key,
required this.scrollController,
this.scrollToText,
});
final ScrollController scrollController;
final String? scrollToText;
@override
State<TodayFaqBottomSheet> createState() => _TodayFaqBottomSheetState();
}
class _TodayFaqBottomSheetState extends State<TodayFaqBottomSheet> {
// 为每个 FAQ 卡片分配 GlobalKey,用于定位渲染位置
final _noDataKey = GlobalKey();
final _watchNoNotificationKey = GlobalKey();
final _watchFaceDelayKey = GlobalKey();
final _watchFaceBlackScreenKey = GlobalKey();
@override
void initState() {
super.initState();
if (widget.scrollToText != null) {
// 等第一帧渲染完成后,计算目标卡片位置并滚动
WidgetsBinding.instance.addPostFrameCallback((_) => _scrollToTarget());
}
}
void _scrollToTarget() {
final l10n = context.l10n;
final text = widget.scrollToText;
GlobalKey? targetKey;
if (text == l10n.todayFaqLinkNoData) {
targetKey = _noDataKey;
} else if (text == l10n.todayFaqLinkWatchNoStatusNotification ||
text == l10n.todayFaqLinkWatchNoStatusAndInteractionNotification) {
targetKey = _watchNoNotificationKey;
} else if (text == l10n.todayFaqLinkWatchFaceDataDelay) {
targetKey = _watchFaceDelayKey;
} else if (text == l10n.todayFaqLinkWatchFaceBlackScreen) {
targetKey = _watchFaceBlackScreenKey;
}
if (targetKey == null) return;
final renderBox =
targetKey.currentContext?.findRenderObject() as RenderBox?;
if (renderBox == null) return;
// 将目标卡片的本地坐标转换为 ListView 滚动视图坐标系中的偏移量
final listRenderObject = widget
.scrollController.position.context.storageContext
.findRenderObject();
if (listRenderObject == null) return;
final targetOffset =
renderBox.localToGlobal(Offset.zero, ancestor: listRenderObject);
final currentOffset = widget.scrollController.offset;
final targetScrollOffset = (currentOffset + targetOffset.dy).clamp(
widget.scrollController.position.minScrollExtent,
widget.scrollController.position.maxScrollExtent,
);
widget.scrollController.animateTo(
targetScrollOffset,
duration: const Duration(milliseconds: 350),
curve: Curves.easeInOut,
);
}
@override
Widget build(BuildContext context) {
... ... @@ -90,11 +156,12 @@ class TodayFaqBottomSheet extends StatelessWidget {
),
Expanded(
child: ListView(
controller: scrollController,
controller: widget.scrollController,
physics: const ClampingScrollPhysics(),
padding: const EdgeInsets.fromLTRB(16, 8, 16, 20),
children: [
_InfoCard(
key: _noDataKey,
title: l10n.todayFaqNoDataTitle,
children: [
_InfoText(
... ... @@ -110,6 +177,7 @@ class TodayFaqBottomSheet extends StatelessWidget {
),
const SizedBox(height: 12),
_InfoCard(
key: _watchNoNotificationKey,
title: l10n.todayFaqWatchNoNotificationTitle,
children: [
_InfoText(
... ... @@ -135,6 +203,7 @@ class TodayFaqBottomSheet extends StatelessWidget {
),
const SizedBox(height: 12),
_InfoCard(
key: _watchFaceDelayKey,
title: l10n.todayFaqWatchFaceDelayTitle,
children: [
_InfoText(
... ... @@ -156,6 +225,7 @@ class TodayFaqBottomSheet extends StatelessWidget {
),
const SizedBox(height: 12),
_InfoCard(
key: _watchFaceBlackScreenKey,
title: l10n.todayFaqWatchFaceBlackScreenTitle,
children: [
_InfoText(
... ... @@ -175,6 +245,7 @@ class TodayFaqBottomSheet extends StatelessWidget {
class _InfoCard extends StatelessWidget {
const _InfoCard({
super.key,
required this.title,
required this.children,
});
... ...