Flutterでボタンを無効にするにはどうすればよいですか?


113

Flutterのコツをつかみ始めたばかりですが、ボタンの有効状態を設定する方法を理解できません。

ドキュメントから、それはonPressedボタンを無効にするためにnull に設定し、それを有効にするために値を与えると言います。ボタンがライフサイクルの間同じ状態を継続する場合、これは問題ありません。

ボタンの有効な状態(またはonPressedコールバック)を何らかの方法で更新できるようにするカスタムステートフルウィジェットを作成する必要があるという印象を受けました。

だから私の質問はどうすればいいですか?これはかなり簡単な要件のように見えますが、それを行う方法に関するドキュメントには何も見つかりません。

ありがとう。


「ボタンがライフサイクルの間同じ状態を続けている場合は問題ありません」という意味を明確にできますか??
セス・ラッド

回答:


125

buildボタンにいくつかのヘルパー関数と、キーオフするいくつかのプロパティと共にステートフルウィジェットを導入したいと思うかもしれません。

  • StatefulWidget / Stateを使用して、条件を保持する変数を作成します(例isButtonDisabled
  • これを最初にtrueに設定します(必要な場合)。
  • ボタンをレンダリングするときonPressed値をいずれかnullまたは何らかの関数に直接設定しないくださいonPressed: () {}
  • 代わりに、3項関数またはヘルパー関数を使用して条件付きで設定します(以下の例)
  • isButtonDisabledこの条件の一部としてを確認し、いずれかnullまたは一部の関数を返します。
  • ボタンが押されたとき(またはボタンを無効にしたいときはいつでも)を使用setState(() => isButtonDisabled = true)して、条件変数を反転します。
  • Flutterはbuild()新しい状態でメソッドを再度呼び出し、ボタンはnullプレスハンドラーでレンダリングされて無効になります。

以下は、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,
    );
  }
}

この例では、インライン3項を使用してTextand を条件付きで設定してい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は通常trueですが、_counterButtonPress()が関数を返すreturn () {}ため、これは意図的なものです。ここで太い矢印を使用したくないのは、関数を実行しnullてボタンを返し、ボタンを無効にするためです。
アシュトントーマス

@AshtonThomasええ、抽出されたメソッド_counterButtonPress()では、説明したとおりですが、抽出を提案する前に、3項演算子でコードを参照していました。最初の例では、ボタンを有効にする必要があるときに_incrementCounter()メソッドを実行します。次回は、私がより正確に何を意味するのかを指摘しようと思います:)
Vit Veres 2018

30
disabledFlutterチームのプロパティを使用して何が問題でしたか?これは直感的ではありません:-/
Curly

1
正しい方法は、AbsorbPointerまたはIgnorePointerを使用することです。onPressedをnullに設定して、ロジックではなく単にウィジェットを使用します。
ejdrian313

93

ドキュメントによると:

「onPressedコールバックがnullの場合、ボタンは無効になり、デフォルトでは、disabledColorのフラットボタンのようになります。」

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

だから、あなたはこのようなことをするかもしれません:

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

2
ドキュメントから判断すると、これは実装方法です。以下のような受け入れ答え特性を有するdisabledElevationdisabledColorDisabledTextColor意図したとおりに動作しません。
JoelBroström19年

このスティーブに感謝するPffは、現在受け入れられている回答のすべてのコードを検討する予定はありませんでした。@ chris84948、これを承認済みの回答に変更することを検討してください。
CularBytes


17

設定

onPressed: null // disables click

そして

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

1
このソリューションでは、の値onPressedは常に関数であるため、ボタンは「クリック可能」としてレンダリングされますが、isEnabledプロパティが設定されている場合、クリックイベントは無視されます。ボタンを実際に無効にするには、RaisedButton(onPressed: isEnabled ? _handleClick : null
Curly

15

特定の限られた数のウィジェットの場合、ウィジェットをIgnorePointerでラップすると、まさにこれignoringが行われます。そのプロパティがtrueに設定されている場合、サブウィジェット(実際には、サブツリー全体)はクリックできません。

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

そうでなければ、サブツリー全体を無効にするつもりなら、AbsorbPointer()を調べてください。


9

有効化と無効化の機能は、ほとんどのウィジェットで同じです。

例、ボタン、スイッチ、チェックボックスなど。

onPressed以下のようにプロパティを設定するだけです

onPressed : null無効なウィジェットを返します

onPressed : (){}またはEnabledウィジェットをonPressed : _functionName返します


6

AbsorbPointerを使用することもでき、次のように使用できます。

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

このウィジェットについて詳しく知りたい場合は、次のリンクをチェックしてくださいFlutter Docs


2
Ignore- / AbsorbPointerは無効化されたスタイルをリマインダーとは見なしません:-)
Pascal

4

これは私の意見では最も簡単な方法です:

RaisedButton(
  child: Text("PRESS BUTTON"),
  onPressed: booleanCondition
    ? () => myTapCallback()
    : null
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.