Flutter — Нужна помощь в правильном использовании заставки Данные для входа с проверкой общих настроек

#android #flutter #sharedpreferences #splash-screen

Вопрос:

Я пытаюсь отобразить заставку с таймером 3 секунды, получая isLoggedIn значение от SharedPreferences . Заставка, которую я использую, — это просто спиннер.

При первой установке приложения все прошло гладко, заставка работала в течение 3 секунд, я вошел в LoginPage нее и ввел учетные данные для входа. Затем приложение сразу перешло на следующую страницу, которая называется /main , внутри которой есть 3 страницы ( BottomNavigationBar ) с /home индексом по умолчанию.

Проблема в том, что в следующий раз, когда я запускаю приложение без его повторной установки, оно не показывает никаких заставок. Это сразу попало на /main страницу. После этого я мгновенно попытался перейти на другую страницу BottomNavigationBar . А затем, через 3 секунды (что, я уверен, связано с таймером), экран автоматически снова запустился и вернулся в /home исходное состояние .

Вот мое splash_screen_page.dart досье:

 import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SplashScreenPage extends StatefulWidget {
  const SplashScreenPage({Key? key}) : super(key: key);

  @override
  State<SplashScreenPage> createState() => _SplashScreenPageState();
}

class _SplashScreenPageState extends State<SplashScreenPage> {
  bool isLoggedIn = false;

  @override
  void initState() {
    super.initState();
    Timer(Duration(seconds: 3), () {
      _navigateUser();

    });
  }

  void _navigateUser() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
    if(isLoggedIn){
      Navigator.pushReplacementNamed(context, "/main");
    }else{
      Navigator.pushReplacementNamed(context, "/login");
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Padding(
            padding: EdgeInsets.all(128),
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: [
                Container(
                    child:
                        // Image(image: AssetImage("assets/splashscreen.png")),
                        const SpinKitFoldingCube(
                  color: Colors.blue,
                  size: 50.0,
                ))
              ],
            )
        )
    );
  }
}
 

Комментарии:

1. Вместо того, чтобы использовать таймер, подождите 3 секунды внутри _navigateUser .

2. @EhsanAskari Только что я попытался переместить таймер, _navigateUser() но результат все тот же. И я тоже пробовал использовать Future.delayed , но это тоже одно и то же. Я запускаю приложение в Chrome (веб), я собираюсь попробовать запустить его на эмуляторе.

3. Проблема решается путем запуска ее на AVD. Спасибо.

Ответ №1:

Может быть, это поможет

 class _SplashScreenPageState extends State<SplashScreenPage> {
    bool isLoggedIn = false;
    
    
    @override
    void initState() {
    super.initState();
    
    login().then((value) {
        if(isLoggedIn){
          Navigator.pushReplacementNamed(context, "/main");
        }else{
          Navigator.pushReplacementNamed(context, "/login");
        }
    });
    
    login(){
        int _jobsRemained = 2;
        while (_jobsRemained > 0) {
            if (!isLoggedIn){
                SharedPreferences prefs = await SharedPreferences.getInstance();
                isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
                _jobsRemained--;
            }
            
            Future.delayed(Duration(seconds: 3)).then((value) => {_jobsRemained--;});
        }
        
    }
  }