颤动根窗口小部件是否应该始终是StatelessWidget?

时间:2019-12-04 07:17:10

标签: flutter

当我在flutter中阅读文档时,我有一个问题,flutter根窗口小部件应始终为StatelessWidget吗?

 class MyApp extends StatelessWidget {
   @override
   Widget build(BuildContext context) {
     return MaterialApp(
       title: 'Flutter Code Sample for Navigator',
       // MaterialApp contains our top-level Navigator
       initialRoute: '/',
       routes: {
         '/': (BuildContext context) => HomePage(),
         '/signup': (BuildContext context) => SignUpPage(),
       },
     );
   }
 }
  1. 因为我认为有时需要调用init函数,并且可能不希望在HomePage中写入该代码。例如:检查令牌是否到期,然后决定转到HomePageLoginPage
  2. 那么最好的选择:我应该将根Widget更改为StatefulWidget,并在其initState函数中加入上述逻辑吗?

3 个答案:

答案 0 :(得分:1)

在监听StatefulWidget时使根窗口小部件成为AppLifecycleState很有用
例如执行恢复作业,例如恢复WebSocket连接

代码段

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {

  AppLifecycleState _lastLifecycleState;


  @override
  void initState() {
    super.initState();
    initPlatformState();
    WidgetsBinding.instance.addObserver(this);

  }

  initPlatformState() async {
    Screen.keepOn(true);   
  }

  Future<void> resumeCallBack() {
    if (sl<WebSocketService>().webSocketState == 'lost') {
      sl<WebSocketService>().initWebSocket();
    }

    if (mounted) {
      setState(() {});
    }
    print("resumeCallBack");
  }

  Future<void> suspendingCallBack() {
    if (mounted) {
      setState(() {});
    }
    print("suspendingCallBack");
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    super.didChangeAppLifecycleState(state);
    print("AppLifecycleState Current state = $state");
    setState(() {
      _lastLifecycleState = state;
    });

    switch (state) {
      case AppLifecycleState.inactive:
      case AppLifecycleState.paused:
      case AppLifecycleState.detached:
      /*case AppLifecycleState.suspending:
        await suspendingCallBack();
        break;*/
      case AppLifecycleState.resumed:
        await resumeCallBack();
        break;
    }
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Template',
      debugShowCheckedModeBanner: false,
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      initialRoute: '/',
      routes: {
        '/': (context) => LoginPage(),

答案 1 :(得分:1)

是的,您可以使用StatefulWidget作为您的根父代。但是,只应在有意义时使用它。

例如,如果您正在初始化并观察某些动画,firebase消息传递,服务,应用程序生命周期状态等,则有时可能需要。

否则,最好使用无状态小部件。

答案 2 :(得分:0)

它可以是 StatefulWidgetStatelessWidget。但是在根中放置 StatefulWidget 会影响您的应用性能,因为 StatefulWidget 中的一个简单状态更改将导致整个小部件树重建并降低您的应用性能。

始终尝试将 StatefulWidgetInheritedWidget 放在小部件树的深处。

针对您的方案更好的解决方案是使用 ProvidersInheritedWidgets 并监听令牌更改,而不是将根小部件更改为有状态