flutter - 为什么即使 Widget 不可见,State 的 build() 方法仍会被调用?

标签 flutter

这个 Flutter 应用示例由一个抽屉和两个可以使用抽屉导航的“页面”(脚手架)组成:

import 'package:flutter/material.dart';

class MyTestDrawer extends StatefulWidget {
  @override
  _MyTestDrawerState createState() => new _MyTestDrawerState();
}

class _MyTestDrawerState extends State<MyTestDrawer> {
  @override
  Widget build(BuildContext context) {

    return new Drawer(child: new ListView(
        children: <Widget>[

          new ListTile(
              leading: new Icon(Icons.pregnant_woman),
              title: new Text('Homepage'),
              onTap: () {
                Navigator.of(context).pushNamed('/');
              }
          ),
          new ListTile(
              leading: new Icon(Icons.group),
              title: new Text('Second page'),
              onTap: () {
                Navigator.of(context).pushNamed('/second');
              }
          ),
          new AboutListTile(
              icon: new Icon(Icons.help)
          )
        ]
    )
    );

  }
}

final MyTestDrawer _drawer = new MyTestDrawer();


class FlutterTestApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    return new MaterialApp(
        title: 'Flutter Test',
        theme: new ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: new HomepageWidget(),
        routes: <String, WidgetBuilder> {
          '/second': (BuildContext context) => new SecondPage(),
        }
    );


  }
}


class HomepageWidget extends StatefulWidget {
  @override
  _HomepageWidgetState createState() => new _HomepageWidgetState();
}

class _HomepageWidgetState extends State<HomepageWidget> {
  @override
  Widget build(BuildContext context) {
    print('build: ' + this.toString());

    return new Scaffold(
      drawer: _drawer,
      appBar: new AppBar(title: new Text('Homepage')),
      body: new Container(
          child: new Center(child: new Text('Homepage'))
      )
    );
  }
}


class SecondPage extends StatefulWidget {
  @override
  _SecondPageState createState() => new _SecondPageState();
}

class _SecondPageState extends State<SecondPage> {
  @override
  Widget build(BuildContext context) {

    print('build: '+ this.toString());

    return new Scaffold(
        drawer: _drawer,
        appBar: new AppBar(title: new Text('Second page')),
        body: new Container(
            child: new Center(child: new Text('Second page'))
        )
    );
  }
}



void main() {
  runApp(new FlutterTestApp());
}

我在 HomepageState 和 SecondPageState build() 方法中都有一个 print 调试语句。

当我运行这个应用程序并在主页第二页之间导航时,我最终在我的日志中得到了这个:

build: _HomepageWidgetState#e0d4a
build: _SecondPageState#06d69
build: _SecondPageState#9c9f7
build: _SecondPageState#db373
build: _SecondPageState#4d4ca
build: _SecondPageState#15247
build: _SecondPageState#06d69
build: _SecondPageState#9c9f7
build: _SecondPageState#db373
build: _SecondPageState#4d4ca
build: _HomepageWidgetState#0d598
build: _HomepageWidgetState#3bb96
build: _HomepageWidgetState#09270
build: _HomepageWidgetState#640bb
build: _HomepageWidgetState#6385a
build: _HomepageWidgetState#ed720
build: _HomepageWidgetState#f45da

似乎每次我在两个页面之间导航时都会创建一个新的 State 对象,并且它的 build() 方法也会不断被调用,即使 Widget 当前不可见也是如此。

显然出了点问题(?)——这是怎么回事?

最佳答案

Flutter 为您推送的每个路由创建一个 State 对象,并在您每次将新路由推送到导航器堆栈时调用其 build() 方法。您目前没有提供从堆栈中弹出任何内容的方法。

您应该避免为 SecondPage 指定抽屉,而是强制用户使用后退按钮导航回主页。这将防止 Navigator 历史堆栈变得任意大。

关于flutter - 为什么即使 Widget 不可见,State 的 build() 方法仍会被调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47075997/

相关文章:

javascript - 列出 Firebase 数据库中的节点

flutter - 为什么父级StatefulWidget中的setState不会更新子级StatefulWidget

flutter - 在CustomScrollView中检测项目退出 View

android - Flutter:如何使用Navigator PushNamed发送屏幕构造器所需的参数

json - 在Flutter的ListView中加载具有特定类别的JSON数据

flutter - ThemeData 中阴影颜色存储在哪里?

android - 从 Android 通过 EventChannel 接收字符串

java - 我如何最好地使用 flutter MethodChannel.invokeMethod 的 java 版本提供多个参数?

flutter - 使用 flutter/dart 加密并使用 CryptoJS 解密 aes 返回空字符串

flutter - 如何从另一个输入动态更新文本值