특정 페이지에서 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(),
},
);
}
}
pageOne에는 pageTwo로 이동하는 버튼이 있습니다.
new FloatingActionButton(
onPressed: () {
Navigator.of(context).pushNamed('/pageTwo');
},
)
내 문제는 안드로이드 화면 하단의 뒤로 화살표를 누르면 pageOne으로 돌아 간다는 것입니다. 이 버튼이 전혀 표시되지 않게하고 싶습니다. 이상적으로는 사용자가 화면에서 손가락을 5 초 동안 누르고 있지 않는 한이 화면에서 나갈 수있는 방법이 없습니다. (저는 유아용 앱을 작성하려고하는데 부모 만 특정 화면에서 이동할 수 있기를 바랍니다.)
답변
대답은 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(),
),
),
),
);
}
답변
Rémi Rousselet이 지적했듯이 WillPopScope
일반적으로 갈 길입니다. 그러나 뒤로 버튼에 직접 반응해야하는 상태 저장 위젯을 개발하는 경우 다음을 사용할 수 있습니다.
https://pub.dartlang.org/packages/back_button_interceptor
참고 :이 패키지의 작성자입니다.
답변
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),
),
],
),
),
);
}
답변
나는 누군가가 이것을 발견하고 그들이 간단한 예를 찾길 바라는 경우에 이것을 여기에 게시하고 있습니다
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"),
)
)
),
);
}
}
답변
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
},
);
}
답변
나는 mixin을 사용했고 WillPopScope 위젯은 나를 위해 일을 할 수 없었습니다. 이것은 내가 찾은 최선의 접근 방식이며 내 의견으로는 WillPopScope보다 훨씬 낫습니다.
final bool canPop = ModalRoute.of(context)?.canPop ?? false;
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(),
답변
대답은 WillPopScope를 사용하고 있다는 것을 알았을 수도 있지만 불행히도 IOS 에서는 스 와이프 하여 이전 페이지 로 돌아갈 수 없으므로 MaterialPageRoute를 사용자 지정해 보겠습니다.
class CustomMaterialPageRoute<T> extends MaterialPageRoute<T> {
@protected
bool get hasScopedWillPopCallback {
return false;
}
CustomMaterialPageRoute({
@required WidgetBuilder builder,
RouteSettings settings,
bool maintainState = true,
bool fullscreenDialog = false,
}) : super(
builder: builder,
settings: settings,
maintainState: maintainState,
fullscreenDialog: fullscreenDialog,
);
}
이제 WillPopScope을 사용할 수 있으며 위로 스 와이프하여 IOS에서 작동합니다. 자세한 답변은 다음과 같습니다 : https://github.com/flutter/flutter/issues/14203#issuecomment-540663717