Flutter基于共享首选项设置启动页面 [英] Flutter set startup page based on Shared Preference

查看:378
本文介绍了Flutter基于共享首选项设置启动页面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在尝试根据共享首选项设置加载不同的页面而没有成功。

I've been trying without success to load different pages according to my Shared Preference settings.

基于stackoverflow中的几篇文章,我得出以下结论解决方案:

Based on several posts found in stackoverflow, i end up with the following solution:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:testing/screens/login.dart';
import 'package:testing/screens/home.dart';

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

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

class _MyAppState extends State<MyApp> {
  Widget page = Login();

  Future getSharedPrefs() async {

    String user = Preferences.local.getString('user');

    if (user != null) {
      print(user);
      this.page = Home();
    }
  }

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

    this.getSharedPrefs();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(home: this.page);
  }
}

class Preferences {
  static SharedPreferences local;

  /// Initializes the Shared Preferences and sets the info towards a global variable
  static Future init() async {
    local = await SharedPreferences.getInstance();
  }
}

变量 user 不为null,因为 print(user)返回预期的值,但 login 屏幕始终处于打开状态。

The variable user is not null because the print(user) returns a value as expected, but the login screen is always being opened.

推荐答案

您的问题是,在getSharedPrefs将来完成之前,您的构建方法将返回。由于它是异步的,因此getSharedPrefs会在调用后立即返回,因此您不等待就将其视为即发即弃。看到您无法等待有意义的initState函数。

Your problem is that your build method returns before your getSharedPrefs future is complete. The getSharedPrefs returns instantly as soon as it's called because it's async and you're treating it as a "Fire and Forget" by not awaiting. Seeing that you can't await in your initState function that makes sense.

这是您要使用FutureBuilder小部件的地方。创建一个返回布尔值(如果需要更多状态,则返回枚举)的Future并将future构建器用作您的家庭孩子以返回正确的小部件。

This is where you want to use the FutureBuilder widget. Create a Future that returns a boolean (or enum if you want more states) and use a future builder as your home child to return the correct widget.

创建您的future

Create your future

Future<bool> showLoginPage() async {
  var sharedPreferences = await SharedPreferences.getInstance();

  // sharedPreferences.setString('user', 'hasuser');

  String user = sharedPreferences.getString('user');

  return user == null;
}

如果用户为null,则返回true。在未来构建器中使用此future来监听值的变化并做出相应的响应。

When user is null this will return true. Use this future in a Future builder to listen to the value changes and respond accordingly.

 @override
  Widget build(BuildContext context) {
    return MaterialApp(home: FutureBuilder<bool>(
     future: showLoginPage(),
     builder: (buildContext, snapshot) {
       if(snapshot.hasData) {
         if(snapshot.data){
           // Return your login here
        return Container(color: Colors.blue);
      }

      // Return your home here
      return Container(color: Colors.red);
    } else {

      // Return loading screen while reading preferences
      return Center(child: CircularProgressIndicator());
    }
  },
));
}

我运行了这段代码,效果很好。当需要登录时,您应该会看到一个蓝屏,当有用户在场时,您会看到一个红屏。取消注释showLoginPage中的行以进行测试。

I ran this code and it works fine. You should see a blue screen when login is required and a red screen when there's a user present. Uncomment the line in showLoginPage to test.

这篇关于Flutter基于共享首选项设置启动页面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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