簡體   English   中英

如何在 Flutter 中正確地將兩個屏幕之一導航給用戶?

[英]How to Navigate one of the two screens to users correctly in Flutter?

最近我正在 Flutter 中開發第一個應用程序,我只知道基礎知識。 所以這就是我目前面臨的問題。

我必須根據舊/新用戶導航兩個屏幕之一,注冊或主頁,所以我所做的就是在這里。

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'Register.dart';
import 'HomePage.dart';

class Authenticate extends StatefulWidget {
  @override
  _AuthenticateState createState() => _AuthenticateState();
}

class _AuthenticateState extends State<Authenticate> {
  String _userName = "";

  @override
  void initState() {
    super.initState();
    _getUserName();
  }

  _getUserName() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      _userName = pref.getString('userName') ?? "";
    });
  }

  Widget build(BuildContext context) {
    if (_userName == "") {
      print('name : $_userName  , NEW user'); // ERROR - why it's printing on console for old User ?
      return Register();
    } else {
      return HomePage(_userName);
    }
  }
}

所以問題是,即使我通過老用戶打開應用程序,它也會打印為新用戶編寫的調試代碼,並且注冊屏幕的屏幕可見性大約為 0.3 秒。

那么我應該怎么做才能解決這個問題?

打印正在發生,因為這行代碼:

SharedPreferences pref = await SharedPreferences.getInstance();

是異步的,這意味着它可能會在稍后的某個時間點調用。 因為首先調用build方法,然后你的_getUserName方法完成,這會導致setState並再次調用build方法。

您可能希望在 sharedPrefernces 初始化之前顯示某種加載程序屏幕,然后決定是顯示Register還是Home頁面。

示例代碼:

class _AuthenticateState extends State<Authenticate> {
  String _userName = "";
  bool _isLoading = true;

  @override
  void initState() {
    super.initState();
    _getUserName();
  }

  _getUserName() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      _userName = pref.getString('userName') ?? "";
      _isLoading = false;
    });
  }

  Widget build(BuildContext context) {
    if (_isLoading) {
      return Center(child: CupertinoActivityIndicator());
    } else if (_userName == "") {
      print('name : $_userName  , NEW user'); // ERROR - why it's printing on console for old User ?
      return Register();
    } else {
      return HomePage(_userName);
    }
  }
}

嘗試這個:

class _AuthenticateState extends State<Authenticate> {
  String _userName;

  @override
  void initState() {
    super.initState();
    _getUserName();
  }

  _getUserName() async {
    SharedPreferences pref = await SharedPreferences.getInstance();
    setState(() {
      _userName = pref.getString('userName') ?? '';
    });
  }

  Widget build(BuildContext context) {
    if (_userName == null) {
      return Center(child: CircularProgressIndicator());
    } else if (_userName == '') {
      print('name : $_userName  , NEW user');
      return Register();
    } else {
      return HomePage(_userName);
    }
  }
}

在這種情況下, _userName最初為null ,只有在_getUserName()返回空字符串或舊用戶名后才會被分配一個值。 當為 null 時,小部件將改為構建進度指示器。 如果您不想要那樣,只需返回一個Container()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM