How do I disable a Button in Flutter?

2020-02-07 21:34发布

I'm just starting to get the hang of Flutter, but I'm having trouble figuring out how to set the enabled state of a button.

From the docs, it says to set onPressed to null to disable a button, and give it a value to enable it. This is fine if the button continues to be in the same state for the lifecycle.

I get the impression I need to create a custom Stateful widget that will allow me to update the button's enabled state (or onPressed callback) somehow.

So my question is how would I do that? This seems like a pretty straightforward requirement, but I can't find anything in the docs on how to do it.

Thanks.

7条回答
Deceive 欺骗
2楼-- · 2020-02-07 21:43

I think you may want to introduce some helper functions to build your button as well as a Stateful widget along with some property to key off of.

  • Use a StatefulWidget/State and create a variable to hold your condition (e.g. isButtonDisabled)
  • Set this to true initially (if that's what you desire)
  • When rendering the button, don't directly set the onPressed value to either null or some function onPressed: () {}
  • Instead, conditionally set it using a ternary or a helper function (example below)
  • Check the isButtonDisabled as part of this conditional and return either null or some function.
  • When the button is pressed (or whenever you want to disable the button) use setState(() => isButtonDisabled = true) to flip the conditional variable.
  • Flutter will call the build() method again with the new state and the button will be rendered with a null press handler and be disabled.

Here's is some more context using the Flutter counter project.

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

In this example I am using an inline ternary to conditionally set the Text and onPressed, but it may be more appropriate for you to extract this into a function (you can use this same method to change the text of the button as well):

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楼-- · 2020-02-07 21:54

Setting

onPressed: null // disables click

and

onPressed: () => yourFunction() // enables click
查看更多
Viruses.
4楼-- · 2020-02-07 21:56

For a specific and limited number of widgets, wrapping them in a widget IgnorePointer does exactly this: when its ignoring property is set to true, the sub-widget (actually, the entire subtree) is not clickable.

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

Otherwise, if you intend to disable an entire subtree, look into AbsorbPointer().

查看更多
▲ chillily
5楼-- · 2020-02-07 21:57

Enable and Disable functionality is same for most of the widgets.

Ex, button , switch, checkbox etc.

Just set the onPressed property as shown below

onPressed : null returns Disabled widget

onPressed : (){} or onPressed : _functionName returns Enabled widget

查看更多
姐就是有狂的资本
6楼-- · 2020-02-07 22:03

The simple answer is onPressed : null gives a disabled button.

查看更多
戒情不戒烟
7楼-- · 2020-02-07 22:08

According to the docs:

"If the onPressed callback is null, then the button will be disabled and by default will resemble a flat button in the disabledColor."

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

So, you might do something like this:

    RaisedButton(
      onPressed: calculateWhetherDisabledReturnsBool() ? null : () => whatToDoOnPressed,
      child: Text('Button text')
    );
查看更多
登录 后发表回答