फ्लैटर में Android "BACK" बटन को कैसे निष्क्रिय या ओवरराइड करें?


110

क्या किसी विशिष्ट पृष्ठ पर 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');
  },
)

मेरी समस्या यह है कि अगर मैं एंड्रॉइड स्क्रीन के निचले भाग में बैक एरो दबाता हूं, तो मैं वापस पेजऑन पर जाता हूं। मैं चाहूंगा कि यह बटन बिल्कुल न दिखे। आदर्श रूप से, मैं इस स्क्रीन से कोई संभव तरीका नहीं निकालना चाहूंगा जब तक कि उदाहरण के लिए उपयोगकर्ता 5 सेकंड के लिए स्क्रीन पर अपनी उंगली दबाए नहीं रखता। (मैं टॉडलर्स के लिए एक ऐप लिखने की कोशिश कर रहा हूं, और चाहूंगा कि केवल माता-पिता विशेष स्क्रीन से बाहर नेविगेट करने में सक्षम हों)।

जवाबों:


198

जवाब है 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(),
        ),
      ),
    ),
  );
}

1
फॉर्म के पॉप को इंटरसेप्ट करने के इच्छुक लोगों के लिए, फॉर्म की onWillPopसंपत्ति का उपयोग करना अधिक सुविधाजनक है । इसकी फॉर्म स्थिति तक पहुंच है और यह देखने के लिए पहले देख सकते हैं कि क्या कोई ऐसा राज्य है जिसे उपयोगकर्ता खोना नहीं चाहता है।
जो लेप्प

हाय @ RémiRousselet, क्या आप मुझे बैक स्टैक प्रबंधन में मदद कर सकते हैं जैसे मेरे पास ए, बी, सी, डी स्क्रीन का ढेर है और मैं डी-> बी या डी-> ए से नेविगेट करना चाहता हूं, फिर मैं कैसे प्रबंधन करूंगा यह। क्या आप मुझे इस पर मार्गदर्शन कर सकते हैं
रवींद्र कुशवाहा

मुझे पता है कि यह उत्तर शायद पुराना है। लेकिन एक मंदिर है! स्पष्टीकरण का विस्तार करने के बारे में सोचें। यह शानदार काम करता है। धन्यवाद।
वैल

1
कोई व्यक्ति पॉप से ​​पहले कुछ करना चाहता है (), इसका उपयोग कर सकता हैonWillPop: () async { onBack(); // "DO YOUR FUNCTION IS HERE WHEN POP" return false; }
Huy Tower

24

जैसा कि रमी रूसेलेट ने बताया, WillPopScopeआमतौर पर जाने का रास्ता है। हालाँकि, यदि आप एक स्टेटफुल विजेट विकसित कर रहे हैं, जो सीधे बैक बटन पर प्रतिक्रिया करना चाहिए, तो आप इसका उपयोग कर सकते हैं:

https://pub.dartlang.org/packages/back_button_interceptor

नोट: मैं इस पैकेज का लेखक हूं।


पूरे सम्मान के साथ, आपको नहीं लगता कि यह टिप्पणी के रूप में बेहतर है?
CopsOnRoad

25
@CopsOnRoad नहीं, क्योंकि यह किसी अन्य उत्तर के लिए एक टिप्पणी नहीं है, बल्कि उसी समस्या को हल करने के लिए पूरी तरह से अलग तरीका है।
मार्क जी

यह एक अच्छा विकल्प है और इसे नजरअंदाज किया जा सकता है अगर यह एक टिप्पणी का हिस्सा होता।
अभिजात_सक्सेना

16

जबकि रेमी का जवाब सही है, आमतौर पर आप केवल बैक बटन को ब्लॉक नहीं करना चाहते हैं, लेकिन उपयोगकर्ता को बाहर निकलने की पुष्टि करना चाहते हैं।

आप पुष्टिकरण संवाद से उत्तर प्राप्त करके इसी तरह कर सकते हैं, क्योंकि 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),
          ),
        ],
      ),
    ),
  );
}

इस उत्तर को क्यों नकारा जाता है? किसी को भी यह लागू है और बुरा अनुभव था?
सामीजार

मैं डिवाइस से बैक बटन दबाने के बाद पहली स्क्रीन पर जाना चाहता हूं। मुझे इस तरह से एक संवाद बॉक्स की आवश्यकता नहीं है। मुझे क्या करना चाहिए
लक्ष्मीयोगेश्वरन

4

मैं इसे यहाँ पोस्ट कर रहा हूँ अगर किसी को यह पता चलता है और उनकी इच्छा होती है कि उन्हें एक सरल उदाहरण मिल जाए 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"),
              )
          )
      ),
    );
  }
}

मैंने सचमुच कल खुद इसका इस्तेमाल किया था। ध्यान रखें कि यह केवल Android के लिए है, Apple का कोई बैक बटन नहीं है। हालाँकि आप शायद मुझे बता सकते हैं कि क्या गलत है इसलिए मैं इसे सुधार सकता हूं, या शायद यह केवल मेरे विशेष एमुलेटर पर काम करता है। मैंने कुछ हफ़्ते में अपना स्पंदन अपडेट नहीं किया है इसलिए शायद यही समस्या है। मुझे बताएं
ब्रायन रद्द

@BryanCancel आपका जवाब केवल तभी काम करता है, जब आपके पास अभी तक कोई धक्का दिया मार्ग नहीं है। विधि विजेट देखें। बाइंडिंग। हैंडल पोपआउट ()। यह पर्यवेक्षकों को पंजीकरण क्रम में सूचित करता है, और जैसे ही यह सच होता है, रुक जाता है। जब धक्का दिए गए मार्ग होते हैं, तो नेविगेटर पहले सच हो जाता है, और फिर आपका पर्यवेक्षक वास्तव में कभी भी कॉल नहीं करता है। दूसरे शब्दों में, आपका कोड केवल एप्लिकेशन को बंद करने से रोकने के लिए काम करता है जब उपयोगकर्ता बैक बटन पर क्लिक करता है, जब कोई और मार्ग नहीं बचता है।
मार्केज

3

आप 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
    },
  );
}

FYI करें, यह इसके बराबर है onWillPop: () async => _allow
लिन

@ लीन हाँ मुझे पता है कि। मैं सिर्फ Future.value()कॉल साझा करना चाहता था ।
CopsOnRoad

3

मैंने मिक्सिन और विलपॉपस्कोप विजेट का उपयोग किया, बस मेरे लिए काम नहीं कर सका। यह सबसे अच्छा दृष्टिकोण है जो मुझे मिला, मेरी राय में विलपोपस्कोप से बहुत बेहतर है।
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(),

2

जवाब शायद आपको पता था कि विलपॉपस्कोप का उपयोग करें , लेकिन दुर्भाग्यवश 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-5-566661717


1

बस Appbar के अग्रणी में एक कंटेनर जोड़ें जो बैक बटन को छुपाता है।

AppBar(
        title: new Text('Page Title'),
        leading: new Container(),
      ),
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.