【问题标题】:Using Flutter, what is the correct way to simulate clicks of a FlatButton?使用Flutter,模拟FlatButton点击的正确方法是什么?
【发布时间】:2017-05-06 14:57:19
【问题描述】:

请看一下这段代码:

final calculate = new FlatButton(
  child: new Text(_calculate),
  onPressed: _valid
      ? () {
          setState(() {
            model.inTemperature = stringToDouble(strTemperature);
            model.calculateOutTemperature();
          });
        }
      : null);

当点击按钮时,setState() 会被一个执行赋值和方法调用的 lambda 调用。完美运行。我想要做的是,如果提交了一个文本字段,则执行相同的setState()

实现这一点的最简单方法是在该按钮上使用performClick()。例如,Android 知道这一点。但是,Flutter 没有这样的方法。所以,我要做的是:

onSubmitted: (newValue) {
  setState(() {
    strTemperature = newValue.trim();
    calculate.onPressed();
  });
},

这也很好用。我的问题是:我可以自己调用onPressed() 回调吗?是否存在我的代码可能会中断的情况?

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    也许最好创建一个可以从按钮和文本字段调用的方法(下面的示例)。我只是觉得你的实现看起来不太好。在我看来,文本字段不应该调用按钮的 onPressed。不过,我没有任何情况会破坏它。

    可能是这样的吗?

    import 'package:flutter/material.dart';
    
    void main() {
      runApp(new MyApp());
    }
    
    class MyApp extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          title: 'Flutter Demo',
          home: new MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
    
      static void _setTemperature() {
        setState(() {
          model.inTemperature = stringToDouble(strTemperature);
          model.calculateOutTemperature();
        });
      }
    
      final calculate = new FlatButton(
        child: new Text(_calculate),
        onPressed: _valid ? () => _setTemperature() : null,
      );
    
      final textField = new TextField(
        controller: _controller,
        onSubmitted: (newValue) {
          setState(() {
            strTemperature = newValue.trim();
            _setTemperature();
          });
        },
      );
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
          appBar: new AppBar(
            title: new Text('TestProject'),
          ),
          body: new Column(
            children: <Widget>[
              calculate,
              textField,
            ],
          ),
        );
      }
    }
    

    【讨论】:

    • 雷纳,谢谢。你当然是对的,我的解决方案看起来有点像一种解决方法。 :-) 将几行共享代码重构为一个方法并从 onPressed() 和 onSubmitted() 调用它是一个干净而好的解决方案。让我们看看其他人是否提出了其他建议。
    • ...现在是公认的答案。 ;-) 谢谢大家。
    【解决方案2】:

    正如其他人所指出的,最好尽量避免“模拟手势”。就您而言,您似乎能够做到这一点。

    但是,对于那些正在寻找真正模拟点击的解决方案(可能是出于测试或其他合法原因)的人,您可以考虑使用 GestureBinding 来调度手势事件,或在渲染框上调用 hitTest获取可接受手势的列表,然后调用其中的一些。这两种方法都有效,更多细节和例子可以在this question找到。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-12
      • 1970-01-01
      • 2020-08-18
      相关资源
      最近更新 更多