【问题标题】:How to prevent Flutter app from scrolling to top after calling setState?调用 setState 后如何防止 Flutter 应用滚动到顶部?
【发布时间】:2019-05-28 16:15:09
【问题描述】:

我在SingleChildScrollView 中有一个ExpansionPanelList。每当我(取消)折叠面板并因此调用setState 时,SingleChildScrollView 就会滚动回顶部。我怎样才能防止这种情况发生?

@override
Widget build(BuildContext context) {
  final _scaffoldKey = new GlobalKey<ScaffoldState>();
  return new Scaffold(
    key: _scaffoldKey,
    appBar: new AppBar(
      title: new Text(widget.title),
    ),
    body: new SingleChildScrollView(
      child: new ExpansionPanelList(
        children: <ExpansionPanel>[
          // panels
        ],
        expansionCallback: (int index, bool isExpanded) {
          setState(() {
            // toggle expanded
          });
        },
      ), // ExpansionPanelList
    ), // SingleChildScrollView
  ); // Scaffold
}

This answer 建议使用自定义ScrollController 并将keepScrollOffset 设置为true,但这是默认值,将其显式设置为true 因此不会改变任何内容。

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    我遇到了同样的问题,不知何故@diegoveloper 的回答并没有解决我的问题

    我最终做的是将SingleChildScrollView 分离为一个独立的StatefulWidget:这也修复了滚动动画。

    我的代码最终变成了类似

    Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text(widget.title),
          ),
          body: MyExpansionList(),
    ...
    
    class MyExpansionListextends StatefulWidget {
    
      @override
      _MyExpansionListState createState() => _MyExpansionListState();
    }
    
    class _MyExpansionListState extends State<MyExpansionList> {
      @override
      Widget build(BuildContext context) {
    
        return Scrollbar(
          isAlwaysShown: true,
          showTrackOnHover: true,
          child: SingleChildScrollView(
            child: Column(
              children: [
                ExpansionPanelList(animationDuration: Duration(seconds: 1),
    

    这样setState() 确实只更新了ExpansionPanelList/ScrollView 而不是整个Scaffold

    我希望这也可以帮助其他面临同样问题的人...

    【讨论】:

      【解决方案2】:

      这是因为您每次重建小部件 (setState) 时都使用新的 Key

      要解决您的问题,只需将下面的代码移到build 方法之外

       final _scaffoldKey = new GlobalKey<ScaffoldState>(); 
      

      像这样:

       final _scaffoldKey = new GlobalKey<ScaffoldState>();
      
          @override
          Widget build(BuildContext context) {
            return new Scaffold(
              key: _scaffoldKey,
              appBar: new AppBar(
                title: new Text(widget.title),
              ),
      

      【讨论】:

      • 谢谢!这也解决了另一个我什至没有意识到的问题,即ExpansionPanelList 根本没有动画。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-05
      • 2012-09-29
      • 2016-07-25
      • 2021-10-24
      • 2016-02-10
      相关资源
      最近更新 更多