मैं स्पंदन में एक बटन को कैसे निष्क्रिय कर सकता हूं?


115

मैं सिर्फ फड़फड़ाहट को पकड़ना शुरू कर रहा हूं, लेकिन मुझे यह पता लगाने में परेशानी हो रही है कि एक बटन की सक्षम स्थिति कैसे सेट की जाए।

डॉक्स से, यह onPressedएक बटन को निष्क्रिय करने के लिए शून्य करने के लिए सेट करने के लिए कहता है , और इसे सक्षम करने के लिए इसे एक मूल्य देता है। यह ठीक है अगर बटन जीवनचक्र के लिए उसी स्थिति में जारी है।

मुझे यह आभास मिलता है कि मुझे एक कस्टम स्टेटफुल विजेट बनाने की आवश्यकता है जो मुझे बटन की सक्षम स्थिति (या ऑनप्रेस्ड कॉलबैक) को किसी तरह अपडेट करने की अनुमति देगा।

तो मेरा सवाल यह है कि मैं ऐसा कैसे करूंगा? यह एक बहुत सरल आवश्यकता की तरह लगता है, लेकिन मैं डॉक्स में कुछ भी नहीं कर सकता कि यह कैसे करना है।

धन्यवाद।


क्या आप स्पष्ट कर सकते हैं कि आपका मतलब क्या है "यह ठीक है अगर बटन जीवनचक्र के लिए उसी स्थिति में जारी है।" ?
सेठ लड्ड

जवाबों:


127

मुझे लगता है कि आप कुछ सहायक कार्यों को buildअपने बटन के साथ-साथ स्टेटफुल विजेट के साथ कुछ प्रॉपर्टी में बंद कर सकते हैं।

  • StatefulWidget / State का उपयोग करें और अपनी स्थिति (जैसे isButtonDisabled) रखने के लिए एक वैरिएबल बनाएं
  • इसे शुरू में सच में सेट करें (यदि आपकी यही इच्छा है)
  • बटन रेंडर करते समय, सीधेonPressednull या तो किसी फंक्शन का मान सेट न करेंonPressed: () {}
  • इसके बजाय , यह सशर्त रूप से एक टर्नरी या एक सहायक कार्य (उदाहरण नीचे) का उपयोग करके सेट करता है
  • isButtonDisabledइस सशर्त के भाग के रूप में जांचें और nullया तो या कुछ फ़ंक्शन पर लौटें ।
  • जब बटन दबाया जाता है (या जब भी आप बटन को अक्षम करना चाहते हैं) setState(() => isButtonDisabled = true)सशर्त चर को फ्लिप करने के लिए उपयोग करते हैं।
  • फ़्लटर build()नए राज्य के साथ फिर से विधि को बुलाएगा और बटन को एक nullप्रेस हैंडलर के साथ प्रदान किया जाएगा और अक्षम किया जाएगा।

फ़्लटर काउंटर परियोजना का उपयोग करते हुए यहां कुछ और संदर्भ दिए गए हैं।

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  bool _isButtonDisabled;

  @override
  void initState() {
    _isButtonDisabled = false;
  }

  void _incrementCounter() {
    setState(() {
      _isButtonDisabled = true;
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text("The App"),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            _buildCounterButton(),
          ],
        ),
      ),
    );
  }

  Widget _buildCounterButton() {
    return new RaisedButton(
      child: new Text(
        _isButtonDisabled ? "Hold on..." : "Increment"
      ),
      onPressed: _isButtonDisabled ? null : _incrementCounter,
    );
  }
}

इस उदाहरण में मैं सशर्त को एक इनलाइन त्रिगुट उपयोग कर रहा हूँ सेट Textऔर onPressed, लेकिन यह आपको एक समारोह में इस निकालने के लिए के लिए अधिक उपयुक्त हो सकता है (आप बटन के पाठ के रूप में अच्छी तरह से बदलने के लिए इस एक ही विधि का उपयोग कर सकते हैं):

Widget _buildCounterButton() {
    return new RaisedButton(
      child: new Text(
        _isButtonDisabled ? "Hold on..." : "Increment"
      ),
      onPressed: _counterButtonPress(),
    );
  }

  Function _counterButtonPress() {
    if (_isButtonDisabled) {
      return null;
    } else {
      return () {
        // do anything else you may want to here
        _incrementCounter();
      };
    }
  }

3
आपको एक तर्क के रूप में वसा तीर फ़ंक्शन को जोड़ने की आवश्यकता है, अन्यथा बटन सक्षम होने पर _incrementCounter () फ़ंक्शन को तुरंत कहा जाएगा। इस तरह से यह वास्तव में बटन जब तक इंतजार करेंगे क्लिक किया जाता है: onPressed इस तरह दिखना चाहिए:onPressed: _isButtonDisabled ? null : () => _incrementCounter
विटामिन Veres

2
@vitVeres जो आमतौर पर सच है लेकिन _counterButtonPress () एक फ़ंक्शन लौटा रहा है return () {}ताकि यह जानबूझकर हो। मैं वसा तीर का उपयोग यहां नहीं करना चाहता क्योंकि मैं चाहता हूं कि फ़ंक्शन निष्पादित और वापस आए nullऔर बटन को अक्षम करें।
एश्टन थॉमस

@AshtonThomas हाँ, निकाली गई विधि में _counterButtonPress () यह बिल्कुल वैसा ही है जैसा आपने समझाया था, लेकिन मैं निष्कर्षण का सुझाव देने से पहले आपको टर्नरी ऑपरेटर के साथ कोड का संदर्भ दे रहा था। आपके पहले उदाहरण में यह _incrementCounter () विधि के निष्पादन का कारण होगा जब बटन को सक्षम किया जाना चाहिए। अगली बार मैं इंगित करने का प्रयास करूँगा कि मेरा क्या मतलब है और अधिक :)
वीट वेर्स

30
एक disabledसंपत्ति, स्पंदन टीम का उपयोग करने में क्या गलत था ? यह सिर्फ सहज नहीं है: - /
घुंघराले

1
सही तरीका AbsorbPointer या IgnorePointer के साथ है। बस null पर स्थापित करने के साथ तर्क के बजाय विजेट तरीका।
ejdrian313

93

डॉक्स के अनुसार:

"अगर ऑनप्रेस्ड कॉलबैक अशक्त है, तो बटन अक्षम हो जाएगा और डिफ़ॉल्ट रूप से अक्षम बॉर्डर में एक फ्लैट बटन जैसा होगा।"

https://docs.flutter.io/flutter/material/RaisedButton-class.html

तो, आप ऐसा कुछ कर सकते हैं:

    RaisedButton(
      onPressed: calculateWhetherDisabledReturnsBool() ? null : () => whatToDoOnPressed,
      child: Text('Button text')
    );

2
डॉक्स से देखते हुए, यह इस तरह लागू किया जाना है। जैसे स्वीकृत उत्तर गुणों के साथ disabledElevation, disabledColorऔर DisabledTextColorइच्छित के अनुसार काम नहीं करेगा।
जोएल ब्रोस्ट्रॉम

इस स्टीव के लिए Pff धन्यवाद, वर्तमान में स्वीकृत उत्तर के सभी कोड के माध्यम से जाने की योजना नहीं बना रहा था। @ chris84948, इसे स्वीकार किए गए उत्तर में बदलने पर विचार करें।
CularBytes


17

स्थापना

onPressed: null // disables click

तथा

onPressed: () => yourFunction() // enables click

1
इस समाधान में मान onPressedहमेशा एक फ़ंक्शन होता है इसलिए बटन को 'क्लिक करने योग्य' के रूप में प्रस्तुत किया जाता है, हालांकि यह क्लिक इवेंट को अनदेखा करेगा यदि isEnabledसंपत्ति सेट है। वास्तव में बटन, उपयोग को अक्षम करने केRaisedButton(onPressed: isEnabled ? _handleClick : null
घुंघराले

15

विजेट की एक विशिष्ट और सीमित संख्या के लिए, उन्हें एक विजेट इग्नोरपॉइंट में लपेटना बिल्कुल यही करता है: जब इसकी ignoringसंपत्ति सही पर सेट होती है, तो उप-विजेट (वास्तव में, संपूर्ण सबट्री) क्लिक करने योग्य नहीं होती है।

IgnorePointer(
    ignoring: true, // or false
    child: RaisedButton(
        onPressed: _logInWithFacebook,
        child: Text("Facebook sign-in"),
        ),
),

अन्यथा, यदि आप एक संपूर्ण सबट्री को अक्षम करने का इरादा रखते हैं, तो AbsorbPointer () में देखें।


9

अधिकांश विजेट के लिए सक्षम और अक्षम कार्यक्षमता समान है।

एक्स, बटन, स्विच, चेकबॉक्स आदि।

onPressedनीचे दिखाए अनुसार संपत्ति सेट करें

onPressed : nullनिष्क्रिय विजेट देता है

onPressed : (){}या सक्षम विजेटonPressed : _functionName देता है


6

आप AbsorbPointer का उपयोग भी कर सकते हैं, और आप इसे निम्न तरीके से उपयोग कर सकते हैं:

AbsorbPointer(
      absorbing: true, // by default is true
      child: RaisedButton(
        onPressed: (){
          print('pending to implement onPressed function');
        },
        child: Text("Button Click!!!"),
      ),
    ),

यदि आप इस विजेट के बारे में अधिक जानना चाहते हैं, तो आप निम्न लिंक फ़्लटर डॉक्स की जाँच कर सकते हैं


2
ध्यान न दें- / AbsorbPointer अक्षम शैलियों को केवल एक REMINDER :-) के रूप में नहीं मानता है
पास्कल

4

मेरी राय में यह सबसे आसान तरीका है:

RaisedButton(
  child: Text("PRESS BUTTON"),
  onPressed: booleanCondition
    ? () => myTapCallback()
    : null
)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.