You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 11:27:05