Flutter + SharedPreferences:构建函数返回null

问题描述

我正试图访问SharedPreferences并创建一个名为“ first_run”的永久文件

在应用程序的第一次启动时,它应该返回“ true”,然后将其更改为false。

我声明了一个将来的函数,基于该函数返回true或false。

现在我得到了一个Wrapper()小部件,其中显示了Loading ...,HomeScreen()或LoginScreen() 基于未来功能的结果。

为什么构建函数返回null? 如何在更新应用程序时避免“ first_run”被删除

这是代码

import 'package:Flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';

import '../screens/home_screen.dart';
import '../screens/login_screen.dart';
import '../providers/auth_provider.dart';

class Wrapper extends StatefulWidget {
  @override
  _WrapperState createState() => _WrapperState();
}

class _WrapperState extends State<Wrapper> {
  FirebaseAuth auth = FirebaseAuth.instance;

  @override
  void initState() {
    AuthProvider().isUserLoggedIn();

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    FutureBuilder(
      future: hasAlreadyStarted(),builder: (context,snapshot) {
        if (snapshot.hasData == true) {
          return LoginScreen();
        } else {
          return CircularProgressIndicator(
            backgroundColor: Colors.deepOrange,);
        }
      },);
  }

  Future <bool> hasAlreadyStarted() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();

    if (prefs.getBool("first_run") == true) {
      prefs.setBool("first_run",false);
      return true;
    } else {
      return false;
    }
  }
}

解决方法

您需要return关键字

@override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: hasAlreadyStarted(),builder: (context,snapshot) {
        if (snapshot.hasData == true) {
          return LoginScreen();
        } else {
          return CircularProgressIndicator(
            backgroundColor: Colors.deepOrange,);
        }
      },);
  }
,

除了需要return(另一个答案已经指出)这一事实之外,您也不应该在每次调用build方法时都产生一个新的Future。

 Future<bool> _yourFuture;

 @override
  void initState() {
    AuthProvider().isUserLoggedIn();

    super.initState();

    _yourFuture = hasAlreadyStarted(); // <= start it once
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _yourFuture,// <= reference it for every build