颤动:根据不同的状态进入不同的页面 [英] flutter: route into different pages according to different status

查看:281
本文介绍了颤动:根据不同的状态进入不同的页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试根据我的应用程序中的用户状态(是否登录)进行重定向,但是由于我不确定如何在方法内部获取BuildContext,因此无法按我的意愿进行操作。

Trying to do a redirect depending on user status in my app (logged in or not), but it won't work as I want it to as I am not sure how to get the BuildContext inside the method.

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:t2/helpers/currentuser.dart';

import 'screens/dashboard.dart';
import 'screens/login.dart';

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

CurrentUser user = new CurrentUser();

Future checkActiveUser() async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

  user.usr = prefs.get('usr');
  user.pwd = prefs.get('pwd');
  if (user.usr.length == 0 && user.pwd.length == 0) {
    user.isLoggedIn = false;
    Navigator.of(x).pushNamedAndRemoveUntil('/dashboard', (Route<dynamic> route) => false);
  } else {
    // Send to login screen
    user.isLoggedIn = false;
    Navigator.of(x).pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
  }

  return user.isLoggedIn;

  /*
// How to read/write to local storage
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
prefs.setInt('counter', counter);
*/
}

class MyApp extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
        title: 'Flutter Demo',
        theme: new ThemeData(
          // This is the theme of your application.
          //
          // Try running your application with "flutter run". You'll see the
          // application has a blue toolbar. Then, without quitting the app, try
          // changing the primarySwatch below to Colors.green and then invoke
          // "hot reload" (press "r" in the console where you ran "flutter run",
          // or press Run > Flutter Hot Reload in IntelliJ). Notice that the
          // counter didn't reset back to zero; the application is not restarted.
          primarySwatch: Colors.blue,
        ),
        home: new MyHomePage(),
        routes: <String, WidgetBuilder>{
          '/dashboard': (BuildContext context) => new Dashboard(),
          '/login': (BuildContext context) => new Login()
        });
  }
}

class MyHomePage extends StatelessWidget {

   var isLoggedIn = checkActiveUser();

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text('Demo Building'),
        ),
        body: new Container(
            child: new Center(
          child: new Column(
            children: <Widget>[new Text('DASHBOARD')],
          ),
        )));
  }
}

如果您有其他建议,我非常高兴!我基本上想在应用程序负载上运行此检查并相应地重定向。

If you have suggestions for a different approach, I'm all ears! I basically want to run this check on app load and redirect accordingly.

致谢,鲍勃

更新的代码:尝试了Hadrien的建议,并得到了更近一步。现在它可以运行,并且我可以访问联系人,但是出现以下错误:

UPDATED CODE: Tried the suggestion from Hadrien, and got a step closer. It now runs and I get contact access but, get the following error:

’导航器操作请求了一个不包含导航器的上下文。用于从导航器推送或弹出路由的上下文必须是作为导航器小部件的后代的小部件的上下文。'

'Navigator operation requested with a context that does not include a Navigator. The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.'

这是更新的代码:

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:t2/helpers/currentuser.dart';

import 'screens/dashboard.dart';
import 'screens/login.dart';

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

CurrentUser user = new CurrentUser();

checkActiveUser(BuildContext context) async {
  SharedPreferences prefs = await SharedPreferences.getInstance();

try {
  user.usr = prefs.get('usr');
  user.pwd = prefs.get('pwd');

  if (user.usr.length == 0 && user.usr.length == 0) {
    user.isLoggedIn = false;
    Navigator
        .of(context)
        .pushNamedAndRemoveUntil('/dashboard', (Route<dynamic> route) => false);
  } else {
      throw new Exception('No user data found');
  }
} catch (e) {
    // Send to login screen
    user.isLoggedIn = false;
    Navigator
        .of(context)
        .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);
}

  /*
// How to read/write to local storage
int counter = (prefs.getInt('counter') ?? 0) + 1;
print('Pressed $counter times.');
prefs.setInt('counter', counter);
*/
}

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

class _MyAppState extends State<MyApp> {
  void initState() {
    super.initState();
    checkActiveUser(context);
  }

  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Welcome to Flutter',
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text('CADSYS'),
        ),
        body: new Center(
          child: new Text('Loading...'),
        ),
      ),
     routes: <String, WidgetBuilder> {
      '/dashboard': (BuildContext context) => new Dashboard(),
      '/login': (BuildContext context) => new Login()
    },
    );
  }
}


推荐答案

I可能会做一些不同的事情...而不是在函数内部推送路由,而是在您的 StatefulWidget 中设置登录状态,然后设置 body 基于此。

I would probably do it a little differently... instead of pushing a route inside a function, set the login state inside your StatefulWidget and then set the body based on that.

body:user.isLoggedIn吗? new Dashboard():new Login(),

然后在代码中的其他位置,您需要检查活动用户并执行 setState((){user.isLoggedIn = true;}); (或false)。

then elsewhere in your code you'll need to check the active user and do setState((){ user.isLoggedIn = true; }); (or false).

登录状态更改时,您的视图将使用新的窗口小部件自动更新。

When the login state changes, your view will automatically update with the new Widget.

这篇关于颤动:根据不同的状态进入不同的页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆