LateInitializationError:字段“显示名称”尚未在 Flutter 共享首选项中初始化?

Posted

技术标签:

【中文标题】LateInitializationError:字段“显示名称”尚未在 Flutter 共享首选项中初始化?【英文标题】:LateInitializationError: Field 'displayName' has not been initialized in Flutter's Shared Prefrence? 【发布时间】:2022-01-23 21:49:56 【问题描述】:

我正在创建一个 Flutter 应用程序,我需要在其中存储用户信息,并且在某种程度上我可以通过 Shared Prefrence 来实现它。

我将数据存储在登录屏幕如下:

    var displayName=jsondata["username"];
    SharedPreferences prefs=await SharedPreferences.getInstance();
    prefs.setString('displayName', displayName);

在我的抽屉屏幕上,我得到了如下相同的数据:

 late String displayName;
 initState() 
  getData();
  super.initState();
 
 getData() async
  SharedPreferences prefs = await SharedPreferences.getInstance();
  displayName=prefs.getString('displayName')!;
 

但是每当我点击抽屉按钮时,都会出现如图所示的错误:

LateInitializationError: 字段“displayName”尚未初始化。

但是当我在抽屉打开时热重新加载我的应用程序时没有错误当我转到其他屏幕并返回抽屉时出现 LateInitialization 错误,

我不知道是什么导致了这个错误

这是我从抽屉中移出的另一个屏幕:

 late String displayName;

getData() async 
   SharedPreferences prefs = await SharedPreferences.getInstance();
  displayName=prefs.getString('displayName')!;
  print(displayName);
    

initState() 
   getData();
   super.initState();
 

     @override
    Widget build(BuildContext context) 
    return Scaffold(
    backgroundColor: Theme.of(context).backgroundColor,
     key: _scaffoldKey,
     drawer: SizedBox(
       width: MediaQuery.of(context).size.width * 0.75 < 400 ? 
     MediaQuery.of(context).size.width * 0.75 : 350,
       child: Drawer(
       child: AppDrawer(
        selectItemName: 'Home',
      ),
    ),
  ),
  appBar: AppBar(
    backgroundColor: Theme.of(context).scaffoldBackgroundColor,
    automaticallyImplyLeading: false,
    title: Row(
      children: <Widget>[
        SizedBox(
          height: AppBar().preferredSize.height,
          width: AppBar().preferredSize.height + 40,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Container(
              alignment: Alignment.centerLeft,
              child: GestureDetector(
                onTap: () 
                  _scaffoldKey.currentState!.openDrawer();
                ,
                child: Icon(
                  Icons.dehaze,
                  color: Theme.of(context).textTheme.headline6!.color,
                ),
              ),
            ),
          ),
        ),

      ],
    ),
  ),

有人可以建议我一个更好的方法吗?提前感谢

【问题讨论】:

可以分享Drawer的代码吗? 【参考方案1】:

您的问题是initState 不是async(也不能是async),因此您的getData 可能(或肯定)在调用build 方法之后完成。由于您在getData 中设置了displayName,并将其标记为late,因此您将收到此错误。这就是它在热重载后工作的原因,因为那时displayName 已经初始化了。

一种可能的解决方案是调用SharedPreferences.getInstance()(这就是为什么您的getData 需要为async)在您的应用程序的早期位置,例如在main() async 函数中,使用a 存储getInstance 的结果ChangeNotifierProvider(或任何其他允许您在此小部件中使用此值的方式),并在getData 中使用其值。这样getData就不需要async了,displayName会在build方法被调用之前被初始化。如果您在多个地方使用SharedPreferences,这会很有用,因为您不必每次都使用await getInstance 的结果。

另一种方法不是将displayName 声明为late,而是将其声明为null,然后在build 方法中,您可以使用FutureBuilder,该FutureBuilder 在执行getData 时完成,并且Scaffold 的建设只有在这个未来完成后才会开始。在这种情况下,您可以在未来未完成时显示进度指示器。

【讨论】:

【参考方案2】:

我忘记添加 setState();

late String displayName;
initState() 
getData();
super.initState();
 
 Future getData() async
 SharedPreferences prefs = await SharedPreferences.getInstance();
 setState(() 
  displayName=prefs.getString('displayName')!;
  );


【讨论】:

以上是关于LateInitializationError:字段“显示名称”尚未在 Flutter 共享首选项中初始化?的主要内容,如果未能解决你的问题,请参考以下文章

LateInitializationError:字段“_userData@32329253”尚未初始化

LateInitializationError:字段尚未在 Flutter 中初始化

LateInitializationError:字段“chatRoomsStream”尚未在 Flutter 中初始化

如何解决 Flutter 中的 LateInitializationError?

LateInitializationError:字段“显示名称”尚未在 Flutter 共享首选项中初始化?

即使我在 initState 中初始化变量,Dart 也会抛出 LateInitializationError