Flutter在main中读取共享首选项然后决定哪个启动页面?

时间:2018-05-22 01:23:23

标签: async-await dart flutter

我想判断在main中启动哪个页面(实际上是登录页面和主页)。所以我必须在首选项中阅读isLogin。怎么做主?

我绑了这些代码:

Performing full restart...                                       
Restarted app in 2,810ms.
[VERBOSE-2:dart_error.cc(16)] Unhandled exception:
Invalid argument(s)
#0      _StringBase.+ (dart:core/runtime/libstring_patch.dart:245:57)
#1      checkIsLogin (file:///Volumes/xs/awesome/uranus/clients/flutter/flutter_asgard/lib/main.dart:17:34)
<asynchronous suspension>
#2      main (file:///Volumes/xs/awesome/uranus/clients/flutter/flutter_asgard/lib/main.dart:29:3)
#3      _startIsolate.<anonymous closure> (dart:isolate/runtime/libisolate_patch.dart:279:19)
#4      _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:165:12)

上面的代码,isLogin是一个全局变量。出现了错误:

@Test
public  void testObjectsAreValid() {
    assertThatExceptionOfType(ExpectedException.class)
        .isThrownBy(obj.setA(null);
    assertThatExceptionOfType(ExpectedException.class)
        .isThrownBy(obj.setB(null);
}

似乎在main中调用异步有问题,如何让它工作?

5 个答案:

答案 0 :(得分:8)

这就是我所做的

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  SharedPreferences.getInstance().then((instance) {
    StorageService().sharedPreferencesInstance = instance; // Storage service is a service to manage all shared preferences stuff. I keep the instance there and access it whenever i wanted.
    runApp(MyApp());
  });
}

然后在Material App Build中

@override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'App Title',
      home: _checkUserLoggedIn()
          ? HomeScreen()
          : LoginPage(),
    );
  }

_checkUserLoggedIn函数

bool _checkUserLoggedIn() {
    return _storageService.getFromShared('isLoggedIn'); //  Just a get method from shared preferences
}

答案 1 :(得分:2)

加载主页,如果用户未登录,则将其替换为LoginPage()

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


Future<Null> checkIsLogin() async {
    String _token = "";
    SharedPreferences prefs = await SharedPreferences.getInstance();
    _token = prefs.getString("token");
    if (_token != "" && _token != null) {
      print("alreay login.");
      //your home page is loaded
    }
    else
    {
      //replace it with the login page
      Navigator.pushReplacement(
        context,
        MaterialPageRoute(builder: (context) => new LoginPage()),
      );
    }
  }

答案 2 :(得分:1)

您需要等待checkIsLogin。

这是我的代码:

Future<Null> main() async {
  SystemChrome.setPreferredOrientations([
    DeviceOrientation.landscapeRight,
    DeviceOrientation.landscapeLeft,
  ]);
  Screen.keepOn(true);
  SharedService.sharedPreferences = await SharedPreferences.getInstance();
  account = SharedService.sharedPreferences.getString("Account");
  password = SharedService.sharedPreferences.getString("Password");
  runApp(new MyApp());
}

答案 3 :(得分:0)

创建一个SplashPage,您可以在MaterialApp()

中作为主路线传递

在SplashPage内,例如initState(),您可以检查登录,而不是将新路由推送到Navigator

SplashPage可以是中心徽标,带有可选动画。

答案 4 :(得分:0)

这是你可以做的

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_robot);
        Intent RobotI = getIntent();
        info = RobotI.getBooleanExtra("info", false);

        // todo: put your ImageView id
        ivRobot = findViewById<ImageView>(R.id.iv_robot)

        imgs[0]=ResourcesCompat.getDrawable(getResources(),R.drawable.robot,null);
        imgs[1]=ResourcesCompat.getDrawable(getResources(),R.drawable.notarobot,null);
        if (info) {
            ivRobot.setImageDrawable(imgs[0]);
        }
        else {
            ivRobot.setImageDrawable(imgs[1]);
        }
    }

更多细节可以参考这篇文章:https://www.ravsam.in/blog/dynamic-home-route-in-flutter-app/