Flutter + SharedPreferences: функция сборки вернула null

Я пытаюсь получить доступ к SharedPreferences и создать постоянный файл с именем first_run.

При первом запуске приложения он должен вернуть true, а затем изменить его на false.

Я объявил будущую функцию, которая будет возвращать истину или ложь в зависимости от этого.

Теперь у меня есть виджет Wrapper (), который показывает либо Загрузка ..., либо HomeScreen (), либо LoginScreen () в зависимости от результата будущей функции.

Почему функция сборки возвращает ноль? Как я могу избежать удаления 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;
    }
  }
}


person Lura    schedule 29.09.2020    source источник


Ответы (2)


Вам нужно 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,
          );
        }
      },
    );
  }
person chunhunghan    schedule 29.09.2020

Помимо того факта, что вам нужен return (что уже указывалось в другом ответе), вы также не должны создавать новое будущее каждый раз, когда вызывается метод сборки.

 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
person nvoigt    schedule 29.09.2020