【问题标题】:initState called after build drawer menu构建抽屉菜单后调用的 initState
【发布时间】:2023-01-11 20:47:12
【问题描述】:

我的脚手架中有一个抽屉菜单,我想显示一些来自 Flutter 安全存储的信息。

class DrawerMenu extends StatefulWidget {
  final Translations translations;
  final PageController controller;

  const DrawerMenu({
    Key? key,
    required this.translations,
    required this.controller,
  }) : super(key: key);

  @override
  State<DrawerMenu> createState() => _DrawerMenuState();
}

String? name;
String? email;

final FlutterSecureStorage storage = FlutterSecureStorage();

class _DrawerMenuState extends State<DrawerMenu> {
  @override
  void initState() {
    getInfo();
    super.initState();
  }

  getInfo() async {
    name = await storage.read(key: 'name');
    email = await storage.read(key: 'email');
  }

@override
  Widget build(BuildContext context) {
    Translations translations = Translations.of(context);
    return Drawer(
      backgroundColor: AppColors.secondaryColor,
      child: SafeArea(
        bottom: false,
        child: Column(
          children: [
            ClipOval(
              child: Container(
                color: AppColors.primaryColor,
                height: 60.0,
                width: 60.0,
                child: Center(
                  child: Text(
                    name![0],
                    style: TextStyle(
                        color: AppColors.secondaryColor,
                        fontSize: 30,
                        fontWeight: FontWeight.bold),
                  ),
                ),
              ),
            ),
      );
  }
}

我第一次遇到这个错误:_CastError(用于空值的空检查运算符)但是,如果我尝试下一步并重新打开抽屉,那就完成了!

我想看看名称在我的抽屉菜单中。

【问题讨论】:

  • 问题是在接收到数据之前正在呈现 UI。所以为了避免这种情况,在 SchedulerBinding 中添加 getInfo。像:SchedulerBinding.instance.addPostFrameCallback({getInfo();});

标签: flutter dart


【解决方案1】:

getInfo()中设置值后必须设置状态。此外,您必须在访问之前检查 name 是否为空。

getInfo() async {
    name = await storage.read(key: 'name');
    email = await storage.read(key: 'email');
    setState({}); <-- add this
  }

@override
  Widget build(BuildContext context) {
    Translations translations = Translations.of(context);
    return Drawer(
      backgroundColor: AppColors.secondaryColor,
      child: SafeArea(
        bottom: false,
        child: Column(
          children: [
            ClipOval(
              child: Container(
                color: AppColors.primaryColor,
                height: 60.0,
                width: 60.0,
                child: Center(
                  child: Text(
                    name==null? "" : name![0] ?? "",  <-- update this
                    style: TextStyle(
                        color: AppColors.secondaryColor,
                        fontSize: 30,
                        fontWeight: FontWeight.bold),
                  ),
                ),
              ),
            ),
      );
  }
}

【讨论】:

    【解决方案2】:

    由于getInfo()是一个异步方法,所以第一次打开抽屉名称和邮箱是没有初始化的。

    为了解决这个问题,

    1. 为姓名和电子邮件提供默认值,
      String name = "";
      String email = "";
      
      1. 然后将这些包裹在setState((){})中,
       getInfo() async {
         setState((){
          name = await storage.read(key: 'name');
          email = await storage.read(key: 'email');
         })
       }
      

    【讨论】:

    • 无法在 initState 中创建异步函数
    猜你喜欢
    • 2015-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    相关资源
    最近更新 更多