264 votes

Comment désactiver un bouton dans Flutter ?

Je commence tout juste à me familiariser avec Flutter, mais j'ai du mal à trouver comment définir l'état d'activation d'un bouton.

Dans la documentation, il est indiqué de définir onPressed à null pour désactiver un bouton, et lui donner une valeur pour l'activer. Cela convient si le bouton reste dans le même état pendant tout le cycle de vie.

J'ai l'impression que je dois créer un widget Stateful personnalisé qui me permettra de mettre à jour l'état activé du bouton (ou le rappel onPressed) d'une manière ou d'une autre.

Ma question est donc : comment faire ? Cela semble être une exigence assez simple, mais je ne trouve rien dans la documentation sur la façon de le faire.

Merci.

0 votes

Pouvez-vous préciser ce que vous entendez par "Cela convient si le bouton reste dans le même état pendant tout le cycle de vie" ? ?

241voto

Ashton Thomas Points 1311

Je pense que vous pouvez introduire des fonctions d'aide pour build votre bouton ainsi qu'un widget d'état et une propriété à utiliser.

  • Utilisez un StatefulWidget/State et créez une variable pour contenir votre condition (par ex. isButtonDisabled )
  • Définissez cette valeur comme vraie au départ (si c'est ce que vous souhaitez).
  • Lors du rendu du bouton, ne définissent pas directement les onPressed à l'une ou l'autre des valeurs suivantes null ou une fonction onPressed: () {}
  • Au lieu de cela, , le fixer conditionnellement en utilisant un ternaire ou une fonction d'aide (exemple ci-dessous)
  • Vérifiez le isButtonDisabled dans le cadre de cette condition et retourner soit null ou une fonction quelconque.
  • Lorsque le bouton est enfoncé (ou à chaque fois que vous souhaitez le désactiver), utilisez la fonction setState(() => isButtonDisabled = true) pour retourner la variable conditionnelle.
  • Flutter appellera le build() avec le nouvel état, et le bouton sera rendu avec une icône de type null le manipulateur de presse et être désactivé.

Voici un peu plus de contexte en utilisant le projet de compteur 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,
    );
  }
}

Dans cet exemple, j'utilise un ternaire en ligne pour définir de manière conditionnelle l'option Text et onPressed mais il est peut-être plus approprié pour vous d'extraire cela dans une fonction (vous pouvez également utiliser cette même méthode pour modifier le texte du bouton) :

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

5 votes

Vous devez ajouter la fonction fat arrow comme argument, sinon la fonction _incrementCounter() sera appelée dès que le bouton sera activé. De cette façon, elle attendra réellement que le bouton soit cliqué : L'onPressed devrait ressembler à ceci : onPressed: _isButtonDisabled ? null : () => _incrementCounter

3 votes

@vitVeres c'est généralement vrai mais le _counterButtonPress() renvoie une fonction return () {} donc c'est intentionnel. Je ne veux pas utiliser la grosse flèche ici car je veux que la fonction s'exécute et retourne null et désactiver le bouton.

0 votes

@AshtonThomas Oui, dans la méthode extraite _counterButtonPress() c'est exactement comme vous l'avez expliqué, mais je faisais référence au code avec l'opérateur ternaire avant que vous ne suggériez l'extraction. Dans votre premier exemple, cela provoquera l'exécution de la méthode _incrementCounter() lorsque le bouton devrait être activé. La prochaine fois, j'essaierai d'expliquer plus précisément ce que je veux dire :)

228voto

Steve Alexander Points 441

Selon les documents :

"Si la callback onPressed est nulle, alors le bouton sera désactivé et ressemblera par défaut à un bouton plat dans la couleur disabledColor."

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

Donc, vous pourriez faire quelque chose comme ça :

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

7 votes

D'après la documentation, c'est ainsi qu'il faut l'implémenter. Avec les propriétés de réponse acceptées comme disabledElevation , disabledColor et DisabledTextColor ne fonctionnera pas comme prévu.

3 votes

Pff merci pour ça Steve, je n'avais pas prévu de passer par tout le code de la réponse actuellement acceptée. @chris84948, pensez à changer ceci en réponse acceptée.

2 votes

Cette réponse devrait être la réponse acceptée, l'approche est plus simple comme prévu par la documentation.

99voto

BINAY THAPA MAGAR Points 1005

La réponse est simple onPressed : null donne un bouton désactivé.

59voto

CopsOnRoad Points 4705

Réglage de

onPressed: null // disables click

et

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

2 votes

Dans cette solution, la valeur de onPressed est toujours une fonction, de sorte que le bouton est rendu comme "cliquable", bien qu'il ignore l'événement de clic si l'option isEnabled est définie. Pour vraiment désactiver le bouton, utilisez RaisedButton(onPressed: isEnabled ? _handleClick : null

30voto

edmond Points 343

Pour un nombre spécifique et limité de widgets, les envelopper dans un widget IgnorePointer fait exactement cela : lorsque son ignoring est définie sur true, le sous-widget (en fait, le sous-arbre entier) n'est pas cliquable.

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

Sinon, si vous avez l'intention de désactiver un sous-arbre entier, regardez dans AbsorbPointer().

0 votes

Comment gérer un écrasement de code ou une erreur dans l'exécution du code pour libérer l'ignorant ?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X