首页 > 解决方案 > 如何在启用键盘时启用或禁用按钮?

问题描述

在验证 TextFormField 期间启用键盘时如何启用或禁用按钮?

class WordsFormPageState extends State<WordsFormPage> {
  var tps = new StringProcessor();
  var _isButtonDisabled = false;
.....
  @override
  Widget build(BuildContext context) {
   final editor = TextFormField(
      decoration: InputDecoration(labelText: 'Your essay'),
      keyboardType: TextInputType.multiline,
      autovalidate: true,
      minLines: 3,
      maxLines: 20,
      validator: (value) {
        if (value.isEmpty) {
          return 'Enter some text';
        }
        if (tps.getWordCount(value) == 100) {
          _isButtonDisabled = false;
        } else {
          _isButtonDisabled = true;
          return "${tps.getWordCount(value)}/100";
        }
        print(_isButtonDisabled);
        return null;
      },
    );
   final form = ListView(
      children: <Widget>[
        ExerciceCardSmall(
          exercice: widget.exercice,
        ),
        Card(
          child: Padding(
            padding: const EdgeInsets.all(10.0),
            child: editor,
          ),
        ),
      ],
    );    
   return Scaffold(
      resizeToAvoidBottomPadding: true,
      appBar: AppBar(
        title: Text(widget.exercice.title),
        actions: <Widget>[
          IconButton(
            icon: Icon(Icons.save),
            onPressed: _isButtonDisabled ? null : () {},
          ),
        ],
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: form,
      ),
    );
  }
}

我希望 IconButton 在字数 != 100 时被禁用,但在隐藏键盘之前该按钮不会被禁用或启用。

编辑:在构建方法中使用 setState 会抛出异常,解决方案是用 addPostFrameCallback 包装它

if (tps.getWordCount(value) == 100) {
       SchedulerBinding.instance
                       .addPostFrameCallback((_) => setState(() {
                                          _isButtonDisabled = false;
                                        }));
} else {
       SchedulerBinding.instance
                       .addPostFrameCallback((_) => setState(() {
                                          _isButtonDisabled = true;
                                        }));
       return "${tps.getWordCount(value)}/100";
}

标签: flutterdartflutter-layout

解决方案


你应该调用setState验证器函数来让 Flutter 知道它已经改变了你页面的状态。

例如:

if (tps.getWordCount(value) == 100) {
  setState(() {
    _isButtonDisabled = false;
  });
} else {
  setState(() {
    _isButtonDisabled = true;
  });
  return "${tps.getWordCount(value)}/100";
}

推荐阅读