Как отключить кнопку в Flutter?

Я только начинаю разглядывать Флаттера, но мне трудно понять, как установить включенное состояние кнопки.

В документах говорится, что для onPressed to null отключить кнопку и дать ей значение для ее включения. Это нормально, если кнопка продолжает находиться в одном и том же состоянии для жизненного цикла.

У меня создается впечатление, что мне нужно создать пользовательский виджет Stateful, который позволит мне как-то обновить статус включенной кнопки (или onPressed callback).

Поэтому мой вопрос: как я это сделаю? Это кажется довольно простым требованием, но я не могу найти что-либо в документах о том, как это сделать.

Благодарю.

Ответ 1

Я думаю, вы можете ввести некоторые вспомогательные функции для build вашей кнопки, а также виджета Stateful вместе с каким-то свойством.

  • Используйте StatefulWidget/State и создайте переменную для сохранения вашего состояния (например, isButtonDisabled)
  • Сначала установите значение true (если это то, что вы желаете)
  • При рендеринге кнопки, прямо не устанавливайте значение onPressed ни null ни какую-либо функцию onPressed:() {}
  • Вместо этого условно установите его с помощью тройной или вспомогательной функции (пример ниже)
  • Проверьте isButtonDisabled как часть этого условного isButtonDisabled и верните либо null либо какую-либо функцию.
  • Когда кнопка нажата (или когда вы хотите отключить кнопку), используйте setState(() => isButtonDisabled = true) чтобы перевернуть условную переменную.
  • Flutter снова вызовет метод build() с новым состоянием, и кнопка будет отображаться с помощью обработчика null пресса и будет отключена.

Вот еще несколько контекстов, использующих проект Counter Flutter.

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

Ответ 2

Согласно документам:

"Если обратный вызов onPressed равен нулю, то кнопка будет отключена и по умолчанию будет напоминать плоскую кнопку в disabledColor".

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

Итак, вы можете сделать что-то вроде этого:

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

Ответ 3

Простой ответ onPressed: null дает отключенную кнопку.

Ответ 4

Для определенного и ограниченного количества виджетов, оборачивая их в виджет IgnorePointer делает именно это: когда его свойство ignoring установлено в значение true, подвиджет (фактически, все поддерево) не активируется,

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

В противном случае, если вы намерены отключить целое поддерево, посмотрите AbsorbPointer().

Ответ 5

Настройка

onPressed: null // disables click

и

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

Ответ 6

Включение и отключение функции одинаковы для большинства виджетов.

Ex, кнопка, переключатель, флажок и т.д.

Просто установите свойство onPressed как показано ниже

onPressed: null возвращает отключенный виджет

onPressed :(){} или onPressed: _functionName возвращает включенный виджет

Ответ 7

Вы также можете использовать AbsorbPointer, и вы можете использовать его следующим образом:

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

Если вы хотите узнать больше об этом виджете, вы можете проверить следующую ссылку Flutter Docs