dart Flutter基于共享首选项设置启动页面

zynd9foi  于 2023-10-13  发布在  Flutter
关注(0)|答案(2)|浏览(107)

我一直试图根据我的共享偏好设置加载不同的页面,但没有成功。
基于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();
  }
}

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

ruoxqz4g

ruoxqz4g1#

您的问题是构建方法在getSharedPrefs future完成之前返回。getSharedPrefs在被调用后立即返回,因为它是一个“FireandForget”,而你不等待它。看到你不能在你的initState函数中等待,这是有意义的。
这就是您要使用FutureBuilder小部件的地方。创建一个返回布尔值的Future(如果你想要更多的状态,也可以使用枚举),并使用一个Future构建器作为你的Home子对象来返回正确的小部件。
创造你的未来

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

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

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

  return user == null;
}

如果user为null,则返回true。在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());
    }
  },
));
}

我运行了这个代码,它工作正常。您应该看到一个蓝屏时,登录是必需的和一个红色的屏幕时,有一个用户存在。取消注解showLoginPage中要测试的行。

bjp0bcyl

bjp0bcyl2#

有一个更干净的方法来做到这一点。假设您有一些路由和一个名为initialized的布尔SharedPreference键。在调用**runApp()方法之前,需要使用WidgetsFlutterBinding.ensureInitialized()**函数。

void main() async {
  var mapp;
  var routes = <String, WidgetBuilder>{
    '/initialize': (BuildContext context) => Initialize(),
    '/register': (BuildContext context) => Register(),
    '/home': (BuildContext context) => Home(),
  };
  print("Initializing.");
  WidgetsFlutterBinding.ensureInitialized();
  await SharedPreferencesClass.restore("initialized").then((value) {
    if (value) {
      mapp = MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'AppName',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        routes: routes,
        home: Home(),
      );
    } else {
      mapp = MaterialApp(
        debugShowCheckedModeBanner: false,
        title: 'AppName',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        routes: routes,
        home: Initialize(),
      );
    }
  });
  print("Done.");
  runApp(mapp);
}

SharedPreference类代码:

class SharedPreferencesClass {
  static Future restore(String key) async {
    final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
    return (sharedPrefs.get(key) ?? false);
  }

  static save(String key, dynamic value) async {
    final SharedPreferences sharedPrefs = await SharedPreferences.getInstance();
    if (value is bool) {
      sharedPrefs.setBool(key, value);
    } else if (value is String) {
      sharedPrefs.setString(key, value);
    } else if (value is int) {
      sharedPrefs.setInt(key, value);
    } else if (value is double) {
      sharedPrefs.setDouble(key, value);
    } else if (value is List<String>) {
      sharedPrefs.setStringList(key, value);
    }
  }
}

相关问题