是否有一种方法可以在特定页面上禁用Android后退按钮?

class WakeUpApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: "Time To Wake Up ?",
      home: new WakeUpHome(),
      routes: <String, WidgetBuilder>{
        '/pageOne': (BuildContext context) => new pageOne(),
        '/pageTwo': (BuildContext context) => new pageTwo(),
      },
    );
  }
}

在第一页,我有一个按钮去第二页:

new FloatingActionButton(
  onPressed: () {    
    Navigator.of(context).pushNamed('/pageTwo');
  },
)

我的问题是,如果我按下android屏幕底部的后退箭头,我就会回到pageOne。我想这个按钮不显示在所有。 理想情况下,除非用户的手指持续按在屏幕上5秒钟,否则我不希望用户有任何办法离开屏幕。(我正在尝试为幼儿编写一个应用程序,希望只有父母能够导航出特定的屏幕)。


当前回答

如果你需要系统返回按钮点击和应用程序栏返回按钮点击有不同的行为:你可以在调用Navigator.of(context).pop()之前删除onWillPop回调:

@override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: onWillPop,
      child: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            onPressed: () {
              ModalRoute.of(context)?.removeScopedWillPopCallback(onWillPop);
              Navigator.of(context).pop();
            },
            icon: const Icon(Icons.arrow_back),
          ),
          title: Text(context.l10n.searchResults),
        ),
        body: MyBody(),
      ),
    );
  }

在这种情况下,当用户点击系统返回按钮时,onWillPop回调将决定是否弹出屏幕。但当用户点击应用栏后退按钮时,屏幕会立即弹出。

其他回答

答案是WillPopScope。它将防止页面被系统弹出。你仍然可以使用Navigator.of(context).pop()

@override
Widget build(BuildContext context) {
  return new WillPopScope(
    onWillPop: () async => false,
    child: new Scaffold(
      appBar: new AppBar(
        title: new Text("data"),
        leading: new IconButton(
          icon: new Icon(Icons.ac_unit),
          onPressed: () => Navigator.of(context).pop(),
        ),
      ),
    ),
  );
}

只是一个简单的方法。用WillPopScope小部件包装脚手架。

  WillPopScope(
    onWillPop: () async => false,
    child: Scaffold();

我使用mixin和WillPopScope小部件只是不能为我完成工作。 这是我发现的最好的方法,在我看来比WillPopScope要好得多。 final bool canPop = ModalRoute.of(context)?canPop ? ?虚假的; 在appbar中使用它:

leading: ModalRoute.of(context)?.canPop ?? false
    ? IconButton(
        onPressed: () {
          Navigator.pop(context);
        },
        icon: (Platform.isAndroid)
            ? const Icon(Icons.arrow_back)
            : const Icon(Icons.arrow_back_ios),
      )
    : Container(),

使用生成的路由,您可以通过这样做返回到目标页面-

AppBar(
        leading: new IconButton(
        icon: new Icon(Icons.arrow_back),
         onPressed: () {
         Navigator.of(context) .pushNamedAndRemoveUntil(AppRouter.dashboard, (route) => false);
         }),
       )

如果你需要系统返回按钮点击和应用程序栏返回按钮点击有不同的行为:你可以在调用Navigator.of(context).pop()之前删除onWillPop回调:

@override
  Widget build(BuildContext context) {
    return WillPopScope(
      onWillPop: onWillPop,
      child: Scaffold(
        appBar: AppBar(
          leading: IconButton(
            onPressed: () {
              ModalRoute.of(context)?.removeScopedWillPopCallback(onWillPop);
              Navigator.of(context).pop();
            },
            icon: const Icon(Icons.arrow_back),
          ),
          title: Text(context.l10n.searchResults),
        ),
        body: MyBody(),
      ),
    );
  }

在这种情况下,当用户点击系统返回按钮时,onWillPop回调将决定是否弹出屏幕。但当用户点击应用栏后退按钮时,屏幕会立即弹出。