2017-05-30 9 views
2

Ich habe eine Anwendung, wo Sie sich anmelden müssen, um fortzufahren (zum Beispiel mit Google).Flutter Redirect auf eine Seite auf initState

Ich möchte den Benutzer umleiten, wenn die Authentifizierung benötigt wird.

Allerdings, wenn ich eine Navigator.of(context).pushNamed("myroute") ausführen. Ich habe folgende Fehlermeldung:

══╡ 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. 

Hier ist ein Beispielcode

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"), 
    ), 
    ), 
    ); 
    } 
} 

Ich glaube, ich etwas falsch mache, vielleicht ein Widget bauen Abbruch dies verursacht. Wie kann ich dies erreichen?

Grundsätzlich gilt: "Ich auf meiner Seite zu gehen, wenn sie nicht angemeldet sind, gehen zur Login-Seite"

Danke, Alexi

Antwort

2

Versuchen Sie Navigator Anruf Verpackung:

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

in einem Rückruf das ist geplant mit addPostFrameCallback:

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

Sie müssen diesen Import am Anfang der Datei:

import 'package:flutter/scheduler.dart'; 

Als Alternative betrachten, wenn Sie nur MyHomePage ‚s build() Methode eine LoginPage anstelle eines Scaffold zurückkehren könnte, wenn der Benutzer nicht angemeldet ist .. in das wird wohl mit der zurück-Taste in Wechselwirkung treten besser, da Sie die Sicherung aus dem Login-Dialog den Benutzer nicht wollen, bevor sie in getan protokollieren

+0

Ihre Die zweite Alternative scheint viel besser zu sein als die erste. Ich habe das hier benutzt. Danke Collin, sehr nützliche Antwort (wie immer) –

0

tat ich dies und arbeitet:

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(); 
} 
Verwandte Themen