2017-05-30 38 views
2

我有一個應用程序需要登錄才能繼續(例如使用Google)。Flutter重定向到initState上的頁面

我想在需要驗證時重定向用戶。

但是,當我運行Navigator.of(context).pushNamed("myroute")。我得到了以下錯誤:

══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ 
I/flutter (5624): The following assertion was thrown building _ModalScopeStatus(active): 
I/flutter (5624): setState() or markNeedsBuild() called during build. 
I/flutter (5624): This Overlay widget cannot be marked as needing to build because the framework is already in the 
I/flutter (5624): process of building widgets. A widget can be marked as needing to be built during the build phase 
I/flutter (5624): only if one of its ancestors is currently building. This exception is allowed because the framework 
I/flutter (5624): builds parent widgets before children, which means a dirty descendant will always be built. 
I/flutter (5624): Otherwise, the framework might not visit this widget during this build phase. 

這裏是一個示例代碼

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

class MyApp extends StatelessWidget { 
    @override 
    Widget build(BuildContext context) { 
    return new MaterialApp(
     title: 'Flutter Demo', 
     theme: new ThemeData(
     primarySwatch: Colors.blue, 
    ), 
     home: new MyHomePage(title: 'Flutter Demo Home Page'), 
     routes: <String, WidgetBuilder> { 
     "login" : (BuildContext context) => new LoginPage(), 
     } 
    ); 
    } 
} 

class MyHomePage extends StatefulWidget { 
    MyHomePage({Key key, this.title}) : super(key: key); 
    final String title; 

    @override 
    _MyHomePageState createState() => new _MyHomePageState(); 
} 

class _MyHomePageState extends State<MyHomePage> { 

    int _counter = 0; 

    @override 
    void initState() { 
     super.initState(); 

     if(!isLoggedIn) { 
     print("not logged in, going to login page"); 
     Navigator.of(context).pushNamed("login"); 
     } 

    } 


    void _incrementCounter() { 
    setState(() { 
     _counter++; 
    }); 
    } 

    void test() { 
    print("hello"); 
    } 

    @override 
    Widget build(BuildContext context) { 

    return new Scaffold(
     appBar: new AppBar(
     title: new Text(widget.title), 
    ), 
     body: new Center(
     child: new Text(
      'Button tapped $_counter time${ _counter == 1 ? '' : 's' }.', 
     ), 
    ), 
     floatingActionButton: new FloatingActionButton(
     onPressed: _incrementCounter, 
     tooltip: 'Increment', 
     child: new Icon(Icons.add), 
    ), // This trailing comma makes auto-formatting nicer for build methods. 
    ); 
    } 

} 

class LoginPage extends StatefulWidget { 
    LoginPage({Key key, this.title}) : super(key: key); 

    final String title; 

    @override 
    _LoginPageState createState() => new _LoginPageState(); 
} 

class _LoginPageState extends State<LoginPage> { 
    @override 
    Widget build(BuildContext context) { 
    print("building login page"); 
    return new Scaffold(
     appBar: new AppBar(
     title: new Text("Sign up/Log In"), 
    ), 
    ), 
    ); 
    } 
} 

我想我做錯了什麼,也許中止控件構建導致此。但是,我怎麼能做到這一點。

基本上是: 「我走了我的網頁上,如果沒有登錄,請登錄頁面」

感謝, 阿列克謝

回答

2

嘗試包裝你的Navigator來電:在回調

Navigator.of(context).pushNamed("login"); 

即計劃與addPostFrameCallback

SchedulerBinding.instance.addPostFrameCallback((_) { 
    Navigator.of(context).pushNamed("login"); 
}); 

你需要此導入你的文件的頂部:

import 'package:flutter/scheduler.dart'; 

作爲備選方案,考慮一下,如果你可以只是MyHomePagebuild()方法返回一個LoginPage代替Scaffold的,如果用戶沒有登錄。在這可能會相互作用與後退按鈕更好,因爲你不希望用戶中途退出登錄對話框中完成在登錄之前,他們

+0

你第二個選擇似乎比第一個更好。我用這個。謝謝科林,非常有用的答案(一如既往) –

0

我這樣做和工作原理:

bool _userNotLogued; 

Scaffold login() { 
    return new Scaffold(
    appBar: new AppBar(
     title: new Text("Login"), 
    ), 
); 
} 

Scaffold home() { 
    return new Scaffold(
    appBar: new AppBar(
     title: new Text("Home"), 
    ), 
); 
} 

@override 
Widget build(BuildContext context) { 
if(_userNotLogued) { 
    return login(); 
} 
return home(); 
}