首页 > 解决方案 > 如何在 Widget build() 之前获取 SharedPrefences 的值,即在构建 UI 之前。?

问题描述

最初当屏幕加载它时显示错误

A non-null String must be provided to a Text widget.

'package:flutter/src/widgets/text.dart':

Failed assertion: line 269 pos 10: 'data != null't

几秒钟后,该值将存储到 _emailSF 变量中。

这是 Stateful 小部件类 HomeScreen 的实例,此任务的主要要求是在 UI 构建发生之前获取 SharedPreferences 字段的值。

getValuesSF 是初始化变量 _emailSF 的值的异步函数;

class DrawerWidget extends State<HomeScreen> {
  final String title;

  String _emailSF;

  DrawerWidget({this.title});

  @override
  void initState() {
    print("*****TAG:HomeScreen*****: initState");
    super.initState();
    getValuesSF();
  }

  @override
  Widget build(BuildContext context) {
    print("*****TAG:HomeScreen*****: $_emailSF");
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        iconTheme: IconThemeData(color: Colors.blue),
        title: Text(
          "Flutter For Beginners",
          style: TextStyle(color: Colors.blue),
        ),
        centerTitle: true,
      ),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.

        child: ListView(
          // Important: Remove any padding from the ListView.

          padding: EdgeInsets.zero,
          children: <Widget>[
            AppDrawer().createHeader(_emailSF),
            AppDrawer().createDrawerItem(icon: Icons.home, text: 'Home'),
            ExpansionTile(
              leading: Icon(Icons.mobile_screen_share),
              title: Text(
                "Examples",
                style: TextStyle(fontSize: 16),
              ),
              children: <Widget>[
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Stack",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/stack');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Scoped Model",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/counter');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Http Request",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/fetch');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "StatefullWidget",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/StateFullWidget');
                    })
              ],
            ),
            AppDrawer().createDrawerItem(
                icon: Icons.open_with,
                text: 'Product',
                onTap: () => Navigator.pushNamed(context, '/product')),
            Divider(),
            AppDrawer().createDrawerItem(
                icon: Icons.mobile_screen_share,
                text: 'Logout',
                onTap: () => Navigator.pushNamed(context, '/product')),
          ],
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[Center(child: Text("Home Screen"))],
        ),
      ),
    );
  }

  getValuesSF() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // Return String
    setState(() => this._emailSF = prefs.getString('email'));

    print(
        "*****TAG:LoginScreen*****:------getValuesSF() Email-------${prefs.getString('email')}");
    //Return double
  }
}

标签: flutterdartflutter-layout

解决方案


没有办法阻止构建,但是您可以选择仅在从共享首选项加载 _emailSF 后显示标题,如下所示。

class DrawerWidget extends State<HomeScreen> {
  final String title;

  String _emailSF;

  DrawerWidget({this.title});

  @override
  void initState() {
    print("*****TAG:HomeScreen*****: initState");
    super.initState();
    getValuesSF();
  }

  @override
  Widget build(BuildContext context) {
    print("*****TAG:HomeScreen*****: $_emailSF");
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.white,
        iconTheme: IconThemeData(color: Colors.blue),
        title: Text(
          "Flutter For Beginners",
          style: TextStyle(color: Colors.blue),
        ),
        centerTitle: true,
      ),
      drawer: Drawer(
        // Add a ListView to the drawer. This ensures the user can scroll
        // through the options in the drawer if there isn't enough vertical
        // space to fit everything.

        child: ListView(
          // Important: Remove any padding from the ListView.

          padding: EdgeInsets.zero,
          children: <Widget>[
            if(_emailSF != null)
            AppDrawer().createHeader(_emailSF),
            AppDrawer().createDrawerItem(icon: Icons.home, text: 'Home'),
            ExpansionTile(
              leading: Icon(Icons.mobile_screen_share),
              title: Text(
                "Examples",
                style: TextStyle(fontSize: 16),
              ),
              children: <Widget>[
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Stack",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/stack');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Scoped Model",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/counter');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "Http Request",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/fetch');
                    }),
                ListTile(
                    contentPadding: EdgeInsets.only(left: 70),
                    title: Text(
                      "StatefullWidget",
                      textAlign: TextAlign.start,
                    ),
                    onTap: () {
                      Navigator.pop(context);
                      Navigator.pushNamed(context, '/StateFullWidget');
                    })
              ],
            ),
            AppDrawer().createDrawerItem(
                icon: Icons.open_with,
                text: 'Product',
                onTap: () => Navigator.pushNamed(context, '/product')),
            Divider(),
            AppDrawer().createDrawerItem(
                icon: Icons.mobile_screen_share,
                text: 'Logout',
                onTap: () => Navigator.pushNamed(context, '/product')),
          ],
        ),
      ),
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[Center(child: Text("Home Screen"))],
        ),
      ),
    );
  }

  getValuesSF() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    // Return String
    setState(() => this._emailSF = prefs.getString('email'));

    print(
        "*****TAG:LoginScreen*****:------getValuesSF() Email-------${prefs.getString('email')}");
    //Return double
  }
}

有什么改变? 而不是AppDrawer().createHeader(_emailSF),使用if(_emailSF != null) AppDrawer().createHeader(_emailSF),


推荐阅读