StatelessWidget中的构建函数不断刷新

时间:2019-06-20 21:15:28

标签: flutter dart

请考虑以下StatelessWidget

class SwitchScreen extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        final testService = Provider.of<TestService>(context);  // Line 1
        Future( () { 
            Navigator.of(context).push(   // Segment 2
                 MaterialPageRoute(builder: (context) => TestScreen())  // Segment 2
            );    // Segment 2
        });

        return Scaffold(body: Center( child: Text("lol") ) );
    }
}

该小部件位于小部件树的根目录的正下方,并由ChangeNotifierProvider包裹:

void main() => runApp(new Main());

class Main extends StatefulWidget {
    _MainState createState() => _MainState();
}

class _MainState extends State<Main> {
    @override
    Widget build(BuildContext context) {
        return MaterialApp(
            title: 'SampleProgram',
            home: ChangeNotifierProvider<TestService>(
                builder: (_) { return TestService(); } ,
                child: SwitchScreen(),
            ),
        );
    }
}

与提供者关联的服务TestService当前为空。 TestScreen只是另一个StatelessWidget,其中包括AppBar,该文本包在Scaffold中。

我希望程序能够完成SwitchScreen的渲染,导航到TestScreen以实现未来,并最终在AppBar内渲染TestScreen。但是,每次进入TestScreen视图时,似乎都会触发一些重建SwitchScreen的事件。然后,该应用弹回SwitchScreen,移至TestScreen以实现未来,并重复此过程。通过使用调试打印语句,我可以确定build完成渲染后立即调用SwitchScreen的{​​{1}}方法。

有趣的是,如果我注释掉第1行,则不会重新触发TestScreen方法。类似地,如果我用其他任何内容替换了段2的全部内容,例如一条打印语句,则build方法也不会继续触发。我怀疑build导致Navigator中的某些值更改,迫使TestService进行重建,因此我覆盖了SwitchScreen中的notifyListeners方法,因为该方法是TestService会受到SwitchScreen影响的唯一方法。

TestService

但是没有打印出字符串。现在,我对重新构建的原因以及提供商和导航器在其中扮演的角色非常好奇。任何帮助将非常感激。

1 个答案:

答案 0 :(得分:0)

代替呼叫

final testService = Provider.of<TestService>(context);

使用

final testService = Provider.of<TestService>(context, listen: false);

在build方法中使用以上行不会导致在调用notifyListeners时重新构建此小部件。