Flutter 设置基于 Shared Preference 的启动页面

Lin*_*ode 4 dart flutter

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

基于在 stackoverflow 中找到的几篇文章,我最终得到了以下解决方案:

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();
  }
}
Run Code Online (Sandbox Code Playgroud)

该变量user不为空,因为它print(user)按预期返回了一个值,但login屏幕始终处于打开状态。

Fil*_*cks 12

您的问题是您的构建方法在您的 getSharedPrefs 未来完成之前返回。getSharedPrefs 一被调用就会立即返回,因为它是异步的,并且您通过不等待将其视为“即发即弃”。看到你不能在你的 initState 函数中等待是有道理的。

这是您想要使用 FutureBuilder 小部件的地方。创建一个 Future 返回一个布尔值(或者枚举,如果你想要更多的状态)并使用一个未来的构建器作为你的家庭孩子来返回正确的小部件。

创造你的未来

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

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

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

  return user == null;
}
Run Code Online (Sandbox Code Playgroud)

当用户为空时,这将返回真。在 Future 构建器中使用这个 Future 来监听值的变化并做出相应的响应。

 @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());
    }
  },
));
}
Run Code Online (Sandbox Code Playgroud)

我运行了这段代码,它工作正常。您应该在需要登录时看到蓝屏,在有用户时看到红屏。取消对 showLoginPage 中的行的注释以进行测试。