【问题标题】:Show a snackbar after navigate in Flutter在 Flutter 中导航后显示快餐栏
【发布时间】:2018-06-03 12:39:37
【问题描述】:

执行操作(例如“保存”)后,用户将返回到应用中的另一个页面。

我想在新页面上显示一个快餐栏以确认操作,但不希望它显示用户是否在没有操作的情况下导航到那里。例如,如果用户保存“事物”,应用程序会将他们发送到“事物”主页并显示“保存的”小吃栏,但如果他们以其他方式转到“事物”主页,我​​不想要“保存”小吃店在那里。

这是我在面板上保存的代码,但目标页面不显示小吃栏 - 无论我将小吃栏放在哪里(导航之前或之后),它都不会执行小吃栏。

Future<Null> saveThatThing() async {
  thing.save();
  thing = new Thing();
  Navigator.of(context).push(getSavedThingRoute());
  Scaffold.of(context).showSnackBar(
    new SnackBar(
      content: new Text('You saved the thing!'),
    ),
  );
}

最好的方法是什么?

【问题讨论】:

标签: flutter dart


【解决方案1】:

如果你像这样为屏幕 Scaffold 创建键会怎么样(把这个对象放在屏幕状态类中):

final GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();

然后将此变量设置为 Scaffold 键,如下所示:

return new Scaffold(
  key: scaffoldKey,
  appBar: new AppBar(
    .......,
  ),

最后显示 SnackBar 只需在屏幕状态类中的某处使用此代码:

scaffoldKey.currentState
    .showSnackBar(new SnackBar(content: new Text("Hello")));

或者您可以将最新代码包装在这样的方法中:

void showInSnackBar(String value) {
scaffoldKey.currentState
    .showSnackBar(new SnackBar(content: new Text(value)));}

然后只需调用此方法并将小吃店消息传递到里面。

如果您想在下一个屏幕上显示小吃店消息,在您离开初始上下文后,只需在下一个屏幕上调用小吃店方法,而不是在第一个屏幕上。

希望这会有所帮助

【讨论】:

  • 我不知道为什么这被否决了。我试试看,谢谢!
  • 谢谢@Deborah。我不确定为什么被否决。如果有什么不起作用,请告诉我,以便我可以尝试提供帮助。
  • 这完全有道理。为什么文档不能这么容易理解? :facepalm
  • 还要确保这个scaffoldKey不在StatelessWidget中。它有时会被重新创建,你会得到惊喜的错误。它进入一个状态.
  • 这行得通,但你必须在你的 initState 中使用 WidgetsBinding.instance.addPostFrameCallback(见这篇文章:didierboelens.com/2019/04/addpostframecallback)。
【解决方案2】:

您必须将结果返回到上一页,该结果将代表页面上显示的操作。

在第一页当您导航到该页面时,请更改一些内容。

bool result=await Navigator.of(context).push(/*Wherever you want*/);

然后在第二页中,当您返回上一页时,将一些结果发送到第一页。

Navigator.of(context).pop(true);

如果工作不成功可以返回false

您可以返回任何类型的对象作为结果

然后在第一页中,您可以检查result 并相应地显示snackBar

bool result=await Navigator.of(context).push(/*Wherever you want*/);
if(result!=null && result==true){
    //Show SnackBar
}else{
    //Some other action if your work is not done
}

【讨论】:

  • 简单有效的解释。谢谢。
  • 谢谢@FabioPagano
【解决方案3】:

由于显示SackBar 需要一个活动的Scaffold,您需要将消息传递到新路由页面,例如getSavedThingRoute(message: 'You saved the thing!'),新页面负责显示消息。

通常我碰巧使用Navigation.pop({'message': 'You saved the thing!', 'error': false}) 来传递消息。

【讨论】:

【解决方案4】:

在第二页的类中,覆盖 initState 方法

@override
void initState() {
  super.initState();
  
  // Shows the SnackBar as soon as this page is opened. 
  Future(() {
    final snackBar = SnackBar(content: Text('Hello World'));
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
  });
}

【讨论】:

  • 这是解决方案的第二部分,您能否建议我如何在第一页设置小吃栏消息?谢谢。
  • 谢谢,我的问题已经解决了。只需在第一页设置小吃栏消息并导航到第二页。我可以在第二页看到小吃栏消息,在第一页设置。再次感谢。
【解决方案5】:

万一有人使用 Flushbar 插件。在 return 语句之前把它放在你的构建函数中。

WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
 
  Flushbar(
    message: "Message from the top",
    flushbarPosition: FlushbarPosition.TOP,
    icon: Icon(
      Icons.info_outline,
      size: 28.0,
      color: Color(0xff00d3fe),
    ),
    flushbarStyle: FlushbarStyle.FLOATING,
    duration: Duration(seconds: 5),
  )..show(_scaffoldKey.currentState.context);
});}

当然不要忘记脚手架键

final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();

【讨论】:

    【解决方案6】:

    在我的情况下,没有显示小吃店的原因是浮动操作按钮,我有一个逻辑来放置工厂,当没有工厂时小吃店没有显示,我没有找到合适的解决方案为此,但放置这样的工厂解决了我的问题。 但是放置 Container() , null 会导致问题。

     Visibility(
              visible: false,
              child: FloatingActionButton(
                  onPressed: () {},
                ),
            );
    

    【讨论】:

      猜你喜欢
      • 2019-04-30
      • 2021-09-01
      • 1970-01-01
      • 2019-10-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多