简体   繁体   English

在动态脚手架中显示 SnackBar 失败

[英]Show a SnackBar in a dynamic Scaffold fails

I have a Home widget with a build method that returns either a Scaffold or a loader widget, based on a boolean.我有一个 Home 小部件,其构建方法基于 boolean 返回 Scaffold 或加载器小部件。 The boolean is set to false, so I return the Scaffold first. boolean 设置为 false,所以我先返回 Scaffold。 I then have a button inside that Scaffold (inside a builder so it will get the Scaffold context for the SnackBar) which changes the bool to true (and as a result returns the loader widget) and after evaluating an input, sets the bool back to false, causing the Scaffold to be returned.然后,我在该 Scaffold 内有一个按钮(在构建器内,因此它将获取 SnackBar 的 Scaffold 上下文),它将 bool 更改为 true(并因此返回加载器小部件)并在评估输入后,将 bool 设置回false,导致返回脚手架。

Within that onPressed() function I also have a SnackBar which I would like to show, but fails with the following error message:在 onPressed() function 中,我还有一个我想显示的 SnackBar,但失败并显示以下错误消息:

Looking up a deactivated widget's ancestor is unsafe. At this point the state of the widget's element tree is no longer stable. To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

(I guess that when I'm returning the loader widget and then returning the Scaffold, something got messed up with the context, I assume the Scaffold returned is a new one, but I am not sure) (我想当我返回 loader 小部件然后返回 Scaffold 时,上下文有些混乱,我认为返回的 Scaffold 是一个新的,但我不确定)

The entire Widget class:整个小部件 class:

class _HomeState extends State<Home> {
  bool loading = false;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return loading
        ? Loading()
        : Scaffold(
            key: _scaffoldKey,
            // backgroundColor: Colors.deepPurple[100],
            appBar: AppBar(
              title: Text(
                'netlush.co.il/home',
                style: TextStyle(
                  fontWeight: FontWeight.w100,
                  fontSize: 16.0,
                ),
              ),
            ),
            body: Padding(
              padding: const EdgeInsets.only(top: 16.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Builder(
                    builder: (context) => RaisedButton(
                      onPressed: () async {
                        setState(() => loading = true);
                        List<UserModel> users = await Api().getCustomers();
                        users = null;
                        if (users == null) {
                          setState(() {
                            loading = false;
                            print('users list is empty');
                            Scaffold.of(context).showSnackBar(SnackBar(
                              content: Text('Context from Builder'),
                              duration: Duration(seconds: 3),
                            ));
                          });
                        } else {
                          setState(() => loading = false);
                          // navigate to users page
                          Navigator.pushNamed(context, '/users',
                              arguments: {'users': users});
                        }
                      },
                      child: Text('Clients*'),
                    ),
                  ),
                  RaisedButton(
                    onPressed: () {},
                    child: Text('Payments'),
                  ),
                ],
              ),
            ),
          );
  }
}

*the user=null statement is there for debugging purposes. *user=null 语句用于调试目的。

Appreciate your help.感谢你的帮助。

You can copy paste run full code below您可以在下面复制粘贴运行完整代码
You can use addPostFrameCallback code snippet您可以使用addPostFrameCallback代码片段

WidgetsBinding.instance.addPostFrameCallback((_) {
                            _scaffoldKey.currentState.showSnackBar(SnackBar(
                              content: Text('Context from Builder'),
                              duration: Duration(seconds: 3),
                            ));
                          });

working demo工作演示

在此处输入图像描述

full code完整代码

import 'package:flutter/material.dart';

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  bool loading = false;
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();

  @override
  Widget build(BuildContext context) {
    return loading
        ? Center(child: CircularProgressIndicator())
        : Scaffold(
            key: _scaffoldKey,
            // backgroundColor: Colors.deepPurple[100],
            appBar: AppBar(
              title: Text(
                'netlush.co.il/home',
                style: TextStyle(
                  fontWeight: FontWeight.w100,
                  fontSize: 16.0,
                ),
              ),
            ),
            body: Padding(
              padding: const EdgeInsets.only(top: 16.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                children: <Widget>[
                  Builder(
                    builder: (context) => RaisedButton(
                      onPressed: () async {
                        setState(() => loading = true);
                        //List<UserModel> users = await Api().getCustomers();
                        await Future.delayed(Duration(seconds: 3), () {});

                        var users;
                        users = null;
                        if (users == null) {
                          setState(() {
                            loading = false;
                            print('users list is empty');
                          });

                          WidgetsBinding.instance.addPostFrameCallback((_) {
                            _scaffoldKey.currentState.showSnackBar(SnackBar(
                              content: Text('Context from Builder'),
                              duration: Duration(seconds: 3),
                            ));
                          });
                        } else {
                          setState(() => loading = false);
                          // navigate to users page
                          Navigator.pushNamed(context, '/users',
                              arguments: {'users': users});
                        }
                      },
                      child: Text('Clients*'),
                    ),
                  ),
                  RaisedButton(
                    onPressed: () {},
                    child: Text('Payments'),
                  ),
                ],
              ),
            ),
          );
  }
}

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: Home(),
    );
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM