Flutter中DraggableScrollableSheet调用jumpTo后自动关闭问题
问题解决:DraggableScrollableSheet点击调用jumpTo后自动关闭,附帧警告处理
问题原因
点击触发togglepanel调用jumpTo时,Sheet的状态还未完成更新就执行了位置跳转,导致内部状态异常,出现自动回弹关闭的情况;而拖拽操作是通过Sheet内部的手势系统处理,状态同步正常,所以功能正常。
另外,“Exceeded sample count in frametime”警告是因为jumpTo瞬间改变Sheet尺寸,导致单帧内UI计算量过大,超出了帧时间限制。
解决方案
1. 延迟执行跳转操作
确保Sheet完成状态更新后再执行跳转,使用WidgetsBinding.instance.addPostFrameCallback延迟调用跳转方法。
2. 同步Sheet状态与控制变量
避免手动维护isPanelOpen状态,通过监听DraggableScrollableController的尺寸变化自动更新状态,防止状态不同步。
3. 替换jumpTo为animateTo
使用带动画的animateTo替代瞬间跳转的jumpTo,分散UI计算压力,消除帧警告。
修正后的代码示例
import 'package:flutter/material.dart'; class TestPage extends StatefulWidget { const TestPage({super.key}); @override State<TestPage> createState() => _TestPageState(); } class _TestPageState extends State<TestPage> { final DraggableScrollableController _sheetController = DraggableScrollableController(); bool _isPanelOpen = false; @override void initState() { super.initState(); // 监听Sheet尺寸变化,自动同步状态 _sheetController.addListener(() { setState(() { _isPanelOpen = _sheetController.size > 0.1; // 大于最小尺寸判定为打开 }); }); } void togglePanel() { WidgetsBinding.instance.addPostFrameCallback((_) { if (_isPanelOpen) { // 关闭Sheet,使用动画过渡 _sheetController.animateTo( 0.1, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } else { // 打开Sheet,使用动画过渡 _sheetController.animateTo( 0.8, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('Draggable Sheet Fix')), body: Stack( children: [ Center( child: ElevatedButton( onPressed: togglePanel, child: Text(_isPanelOpen ? '关闭面板' : '打开面板'), ), ), DraggableScrollableSheet( controller: _sheetController, initialChildSize: 0.1, minChildSize: 0.1, maxChildSize: 0.8, builder: (context, scrollController) { return Container( color: Colors.lightBlue[100], child: ListView.builder( controller: scrollController, itemCount: 20, itemBuilder: (context, index) => ListTile(title: Text('列表项 $index')), ), ); }, ), ], ), ); } @override void dispose() { _sheetController.dispose(); super.dispose(); } }
关键说明
- 使用
addPostFrameCallback确保在当前帧构建完成后再执行跳转,避免状态冲突。 - 通过监听控制器尺寸自动更新
_isPanelOpen,避免手动维护状态导致的不同步。 animateTo配合合理的动画时长,减少单帧计算量,解决“Exceeded sample count in frametime”警告。
内容的提问来源于stack exchange,提问作者Milan Gaur
相关产品推荐
相关产品推荐

