我刚开始掌握Flutter的窍门,但我不知道如何设置按钮的启用状态。

从文档中,它说将onPressed设置为null来禁用按钮,并给它一个值来启用它。如果按钮在生命周期中继续处于相同的状态,这是没问题的。

我得到的印象是,我需要创建一个自定义的有状态小部件,它将允许我以某种方式更新按钮的启用状态(或onPressed回调)。

我的问题是我该怎么做?这似乎是一个非常简单的要求,但我在文档中找不到任何关于如何做到这一点的东西。

谢谢。


当前回答

这个答案是基于更新的按钮TextButton/ElevatedButton/OutlinedButton颤振2.x

不过,按钮是基于onPressed属性启用或禁用的。如果该属性为空,则按钮将被禁用。如果你将函数分配给onPressed,那么按钮将被启用。 在下面的代码片段中,我展示了如何启用/禁用按钮,并相应地更新它的样式。

这篇文章也说明了如何将不同的风格应用到新的 颤振2。x按钮。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  bool textBtnswitchState = true;
  bool elevatedBtnSwitchState = true;
  bool outlinedBtnState = true;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: <Widget>[
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                TextButton(
                  child: Text('Text Button'),
                  onPressed: textBtnswitchState ? () {} : null,
                  style: ButtonStyle(
                    foregroundColor: MaterialStateProperty.resolveWith(
                      (states) {
                        if (states.contains(MaterialState.disabled)) {
                          return Colors.grey;
                        } else {
                          return Colors.red;
                        }
                      },
                    ),
                  ),
                ),
                Column(
                  children: [
                    Text('Change State'),
                    Switch(
                      value: textBtnswitchState,
                      onChanged: (newState) {
                        setState(() {
                          textBtnswitchState = !textBtnswitchState;
                        });
                      },
                    ),
                  ],
                )
              ],
            ),
            Divider(),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ElevatedButton(
                  child: Text('Text Button'),
                  onPressed: elevatedBtnSwitchState ? () {} : null,
                  style: ButtonStyle(
                    foregroundColor: MaterialStateProperty.resolveWith(
                      (states) {
                        if (states.contains(MaterialState.disabled)) {
                          return Colors.grey;
                        } else {
                          return Colors.white;
                        }
                      },
                    ),
                  ),
                ),
                Column(
                  children: [
                    Text('Change State'),
                    Switch(
                      value: elevatedBtnSwitchState,
                      onChanged: (newState) {
                        setState(() {
                          elevatedBtnSwitchState = !elevatedBtnSwitchState;
                        });
                      },
                    ),
                  ],
                )
              ],
            ),
            Divider(),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                OutlinedButton(
                  child: Text('Outlined Button'),
                  onPressed: outlinedBtnState ? () {} : null,
                  style: ButtonStyle(
                      foregroundColor: MaterialStateProperty.resolveWith(
                    (states) {
                      if (states.contains(MaterialState.disabled)) {
                        return Colors.grey;
                      } else {
                        return Colors.red;
                      }
                    },
                  ), side: MaterialStateProperty.resolveWith((states) {
                    if (states.contains(MaterialState.disabled)) {
                      return BorderSide(color: Colors.grey);
                    } else {
                      return BorderSide(color: Colors.red);
                    }
                  })),
                ),
                Column(
                  children: [
                    Text('Change State'),
                    Switch(
                      value: outlinedBtnState,
                      onChanged: (newState) {
                        setState(() {
                          outlinedBtnState = !outlinedBtnState;
                        });
                      },
                    ),
                  ],
                )
              ],
            ),
          ],
        ),
      ),
    );
  }
}

其他回答

简单的答案是onPressed: null给出一个禁用按钮。

你也可以使用吸收指针,你可以用下面的方式使用它:

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

如果您想了解有关此小部件的更多信息,可以查看以下链接Flutter Docs

在我看来,这是最简单的方法:

RaisedButton(
  child: Text("PRESS BUTTON"),
  onPressed: booleanCondition
    ? () => myTapCallback()
    : null
)

有两种方法:

1- https://stackoverflow.com/a/49354576/5499531

2-你可以使用MaterialStatesController:

final _statesController = MaterialStatesController();

然后将状态更改为:

_statesController.update(
   MaterialState.disabled,
   true, // or false depending on your logic
);

在你的按钮上

ElevatedButton(
    onPressed: _onPressed,
    statesController: _statesController,
    child: Text("Awesome"),
),

此外,你可以改变按钮的风格,当禁用: 在主题设置中:

....
elevatedButtonTheme: ElevatedButtonThemeData(
              style: ElevatedButton.styleFrom(
                backgroundColor: colors.primary500, // set your own color
                textStyle: button, // set your own style
                onPrimary: colors.onPrimary100, // set your own color
                enableFeedback: true,
                disabledBackgroundColor: colors.primary300, // set your own color
                disabledForegroundColor: colors.primary300, // set your own color
                disabledMouseCursor: SystemMouseCursors.forbidden, // when is disable the change the cursor type
              ),
            ),
...

我喜欢为此使用flutter_mobx,并对状态进行处理。

接下来我使用一个观察者:

Container(child: Observer(builder: (_) {
  var method;
  if (!controller.isDisabledButton) method = controller.methodController;
  return RaiseButton(child: Text('Test') onPressed: method);
}));

控制器侧:

@observable
bool isDisabledButton = true;

然后在控件中,您可以随心所欲地操作这个变量。

参考文献。: Flutter mobx