如何在Widget build()之前(即在构建UI之前)获取SharedPrefences的值?

时间:2019-11-29 11:50:46

标签: flutter dart flutter-layout

最初在屏幕加载时显示错误

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变量中。

这是有状态窗口小部件类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
  }
}

1 个答案:

答案 0 :(得分:1)

无法阻止构建,但是您可以选择仅在从共享首选项加载_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),