Как отключить или переопределить кнопку Android "НАЗАД" во Флаттере?
Есть ли способ отключить кнопку возврата 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(),
},
);
}
}
На странице One у меня есть кнопка для перехода на страницу Two:
new FloatingActionButton(
onPressed: () {
Navigator.of(context).pushNamed('/pageTwo');
},
)
Моя проблема в том, что если я нажму стрелку Назад в нижней части экрана Android, я вернусь на страницу One. Я бы хотел, чтобы эта кнопка вообще не появлялась. В идеале я бы не хотел выходить из этого экрана, если, например, пользователь не удерживает палец на экране в течение 5 секунд. (Я пытаюсь написать приложение для малышей, и хотел бы, чтобы только родители могли перемещаться из определенного экрана).
Ответы
Ответ 1
Ответ будет 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(),
),
),
),
);
}
Ответ 2
Как отметил Реми Русселе, WillPopScope
- это обычно путь. Однако, если вы разрабатываете виджет с отслеживанием состояния, который должен напрямую реагировать на кнопку возврата, вы можете использовать это:
https://pub.dartlang.org/packages/back_button_interceptor
Ответ 3
Я размещаю это здесь, если кто-то найдет это и пожелает, чтобы они нашли простой пример https://gist.github.com/b-cancel/0ca372017a25f0c120b14dfca3591aa5
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(new BackButtonOverrideDemoWidget());
class BackButtonOverrideDemoWidget extends StatefulWidget{
@override
_BackButtonOverrideDemoWidgetState createState() => new _BackButtonOverrideDemoWidgetState();
}
class _BackButtonOverrideDemoWidgetState extends State<BackButtonOverrideDemoWidget> with WidgetsBindingObserver{
//-------------------------Test Variable
bool isBackButtonActivated = false;
//-------------------------Required For WidgetsBindingObserver
@override
void initState() {
super.initState();
WidgetsBinding.instance.addObserver(this);
}
@override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
super.dispose();
}
//-------------------------Function That Triggers when you hit the back key
@override
didPopRoute(){
bool override;
if(isBackButtonActivated)
override = false;
else
override = true;
return new Future<bool>.value(override);
}
//-------------------------Build Method
@override
Widget build(BuildContext context) {
return new Directionality(
textDirection: TextDirection.ltr,
child: new Container(
color: (isBackButtonActivated) ? Colors.green : Colors.red,
child: new Center(
child: new FlatButton(
color: Colors.white,
onPressed: () {
isBackButtonActivated = !isBackButtonActivated;
setState(() {});
},
child: (isBackButtonActivated) ?
new Text("DeActive the Back Button") : new Text("Activate the Back Button"),
)
)
),
);
}
}
Ответ 4
Вы можете использовать Future.value(bool)
для управления кнопкой возврата.
bool _allow = true;
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(appBar: AppBar(title: Text("Back"))),
onWillPop: () {
return Future.value(_allow); // if true allow back else block it
},
);
}
Ответ 5
Вы должны использовать метод popAndPushNamed
вместо pushNamed
. Он выдает текущий маршрут и нажимает желаемый маршрут.
При этом ваш код FAB должен выглядеть следующим образом:
new FloatingActionButton(
onPressed: () {
Navigator.popAndPushNamed(context, '/pageTwo');
},
)
Ответ 6
Я использовал миксин и виджет WillPopScope, но не смог выполнить свою работу за меня.
Это лучший подход, который я нашел, на мой взгляд, намного лучше, чем WillPopScope.
final bool canPop = ModalRoute.of(context)?.canPop ?? false;
Использовал это так в панели приложений:
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(),
Ответ 7
Хотя Remi ответ правильный, обычно вы не хотите просто блокировать кнопку "Назад", но хотите, чтобы пользователь подтвердил выход.
Вы можете сделать это аналогичным образом, получив ответ в диалоговом окне подтверждения, потому что onWillPop
- это будущее.
@override
Widget build(BuildContext context) {
return WillPopScope(
child: Scaffold(...),
onWillPop: () => showDialog<bool>(
context: context,
builder: (c) => AlertDialog(
title: Text('Warning'),
content: Text('Do you really want to exit'),
actions: [
FlatButton(
child: Text('Yes'),
onPressed: () => Navigator.pop(c, true),
),
FlatButton(
child: Text('No'),
onPressed: () => Navigator.pop(c, false),
),
],
),
),
);
}
Ответ 8
Вы можете использовать следующий метод:
new FloatingActionButton(
onPressed: () {
Navigator.of(context).pushReplacementNamed('/pageTwo');
},
)
Надеюсь, это поможет. Спасибо