-
-
Notifications
You must be signed in to change notification settings - Fork 67
Closed
Description
大佬你好,我按照
Originally posted by @wksmile in #103 的方法确实能实现展开位置固定,但是有一个问题,就是当展开的内容很长超过一屏的时候展开收起位置就不能固定了。
如图,展开很长位置固定失效。
写个一个 demo 问题复现代码如下:
scroll_list_page.dart 文件
import './expand_item.dart';
class MessageItem {
final String content;
final List<String> children;
const MessageItem({required this.content, required this.children});
}
@RoutePage()
class ScrollListPage extends StatefulWidget {
const ScrollListPage({super.key});
@override
State<ScrollListPage> createState() => _scrollListPage();
}
class _scrollListPage extends State<ScrollListPage> with WidgetsBindingObserver {
final ScrollController scrollController = ScrollController();
late ListObserverController observerController;
late ChatScrollObserver chatObserver;
List<MessageItem> messages = [
MessageItem(
content:
'''监测** - **尽可能上传最近的数据**,例如体温、心率血压、呼吸频率等,这有助于更精确地分析头痛原因。 - 记录头痛的发生时间、频率和持续时间,以及是否伴随其他症状。#### **4. 改善睡眠** - 保持规律睡眠时间,晚上尽量避免在屏幕前时间过长。 - 可在睡前喝些温牛奶,或通过泡脚及放松呼吸训练,帮助身体进入更深的睡眠状态。---### **需要特别关注的情况**如果头痛伴有以下症状,请及时反馈或联系医生:- 持续加剧的头痛,并伴有明显的视力模糊、呕吐或晕厥。- 任何异常变化,比如剧烈恶心、无法言语或肢体无力。请根据建议逐步调节,如果头痛持续存在或频繁加重,及时向我反馈最新的症状与监测数据!''',
children: [
'''onize the data.- restingHeartRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:25:00: 30.0 BPMYou can kindly remind the user to synchronize the data.Reference: Apple Health[Retrieve respiratory health metrics to assess any breathing-related issues linked to headaches.]:- respiratoryRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:20:00: 12.0 BPMYou can kindly remind the user to synchronize the data.- oxygenSaturations:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 1.0 %You can kindly remind the user to synchronize the data.Reference: Apple Health[Query lab results for indicators related to metabolic or systemic conditions that might cause headaches.]:No related information was found. Please verify if the relevant data has been uploaded or synchronized''',
]),
MessageItem(
content:
'''这条消息第一个展开内容很多长展开有问题,位置不能固定''',
children: [
'''Identify the cause of the user's headache and provide possible solutions or recommendations.</summary>[Query vital signs data to check for any abnormalities that could be associated with headaches.]:- bodyTemperatures:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:23:00: 37.78 °CYou can kindly remind the user to synchronize the data.- restingHeartRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:25:00: 30.0 BPMYou can kindly remind the user to synchronize the data.- bloodGlucoses:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:23:00: 100.0 mg/dLYou can kindly remind the user to synchronize the data.- systolicPressures:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 100.0 mmHgYou can kindly remind the user to synchronize the data.- diastolicPressures:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 60.0 mmHgYou can kindly remind the user to synchronize the data.- oxygenSaturations:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 1.0 %You can kindly remind the user to synchronize the data.- hrvDatas:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:25:00: 30.0 msYou can kindly remind the user to synchronize the data.- heartRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 20:22:00: 101.0 BPMYou can kindly remind the user to synchronize the data.- respiratoryRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:20:00: 12.0 BPMYou can kindly remind the user to synchronize the data.Reference: Apple Health[Retrieve heart-related metrics to identify any cardiovascular factors contributing to headaches.]:- hrvDatas:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:25:00: 30.0 msYou can kindly remind the user to synchronize the data.- heartRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 20:22:00: 101.0 BPMYou can kindly remind the user to synchronize the data.- restingHeartRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:25:00: 30.0 BPMYou can kindly remind the user to synchronize the data.Reference: Apple Health[Retrieve respiratory health metrics to assess any breathing-related issues linked to headaches.]:- respiratoryRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:20:00: 12.0 BPMYou can kindly remind the user to synchronize the data.- oxygenSaturations:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 1.0 %You can kindly remind the user to synchronize the data.Reference: Apple Health[Query lab results for indicators related to metabolic or systemic conditions that might cause headaches.]:No related information was found. Please verify if the relevant data has been uploaded or synchronized''',
'''respiratory health metrics to assess any breathing-related issues linked to headaches.]:- respiratoryRates:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:20:00: 12.0 BPMYou can kindly remind the user to synchronize the data.- oxygenSaturations:Data is not available for 2025-01-06 - 2025-01-13. Here is the last valid data on 2024-11-18 17:24:00: 1.0 %You can kindly remind the user to synchronize the data.Reference: Apple Health[Query lab results for indicators related to metabolic or systemic conditions that might cause headaches.]:No related information was found. Please verify if the relevant data has been uploaded or synchronized''',
'''data.Reference: Apple Health[Query lab results for indicators related to metabolic or systemic conditions that might cause headaches.]:No related information was found. Please verify if the relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
MessageItem(content: '''步数数据!''', children: [
'''A relevant data has been uploaded or synchronized''',
]),
];
@override
void initState() {
super.initState();
initChatObserver();
}
@override
void dispose() {
observerController.controller?.dispose();
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
@override
void didChangeMetrics() {
super.didChangeMetrics();
chatObserver.observeSwitchShrinkWrap();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
resizeToAvoidBottomInset: true,
body: Align(
alignment: Alignment.topCenter,
child: ListViewObserver(
controller: observerController,
child: ListView.builder(
physics: ChatObserverClampingScrollPhysics(observer: chatObserver),
itemCount: messages.length,
reverse: true,
controller: scrollController, // 设置 ScrollController
shrinkWrap: chatObserver.isShrinkWrap,
padding: const EdgeInsets.only(left: 16, right: 16, top: 20, bottom: 10),
itemBuilder: (context, index) {
return _itemBuilder(
context,
index,
);
},
),
),
));
}
Widget _itemBuilder(BuildContext context, int index) {
MessageItem item = messages[index];
return Container(
margin: EdgeInsets.only(bottom: 10),
width: 150,
color: Colors.grey[200],
child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [
...item.children.map((e) => ExpandBox(childContent: e, callback: expandCb, index: index)),
Text(item.content),
]));
}
void initChatObserver() {
observerController = ListObserverController(
controller: scrollController,
)..cacheJumpIndexOffset = false;
chatObserver = ChatScrollObserver(observerController)
..fixedPositionOffset = 5
..toRebuildScrollViewCallback = () {
setState(() {});
};
}
void expandCb(int index) {
// 对比上一个 item 来定位
final refItemIndex = index + 1;
chatObserver.standby(
mode: ChatScrollObserverHandleMode.specified,
refIndexType: ChatScrollObserverRefIndexType.itemIndex,
refItemIndex: refItemIndex,
refItemIndexAfterUpdate: refItemIndex,
);
}
}
expand_item.dart 文件
class ExpandBox extends StatefulWidget {
final String childContent;
final Function? callback;
final int index;
const ExpandBox({
super.key,
required this.childContent,
this.callback,
required this.index,
});
@override
State<ExpandBox> createState() => _ExpandBoxState();
}
class _ExpandBoxState extends State<ExpandBox> {
bool isExpanded = false;
@override
Widget build(
BuildContext context,
) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
ElevatedButton(
onPressed: () {
setState(() {
isExpanded = !isExpanded;
});
widget.callback!(widget.index);
},
child: isExpanded ? Text('收起') : Text('展开')),
if (isExpanded) Text(widget.childContent),
if (isExpanded) Text('Expanded content'),
],
);
}
}
Metadata
Metadata
Assignees
Labels
No labels