我应该使用 getter 来构建小部件子树吗?

Should I use getters for building widget sub-tree?

今天我遇到了Flutter中新的代码编写风格。通常我使用下一种方式来声明小部件树:

这是我们在创建新的 flutter 项目后得到的 class(为了节省您的时间,我只发布构建方法):


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );

我今天在 github 的某个 flutter 项目中看到的区别是将小部件声明为 getters :


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            textPushed,
            counterText,
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  Widget get textPushed {
    return Text(
      'You have pushed the button this many times:',
    );
  }

  Widget get counterText {
    return Text(
      '$_counter',
      style: Theme.of(context).textTheme.headline4,
    );

我从未见过这种使用 getter 构建小部件的方法,我想知道这是否是一种好的做法,为什么?

我将把这个方法与 flutter 中使用的主要方法进行比较,后者为每个您认为应该为其定义 getter 的小部件创建一个小部件 class

这是不好的做法,因为:

  1. 当您创建带有函数的小部件时,没有与该小部件关联的元素,并且您正在传递和使用主小部件的上下文

  2. 当您为小部件创建一个单独的 class 时,您可以选择以多种方式重构它,例如使其有状态或无状态而没有任何麻烦

  3. 当你在一个单独的窗口中定义一个小部件时很难调试class你会给它一个名字,并且很容易在小部件树中跟踪那个小部件并调试它

还有很多其他的东西,所描述的方法类似于反应中的功能组件,在 flutters GitHub 页面中对此有很好的讨论,一些优秀的程序员参与了你可以看到更多这里关于这个主题的知识是 link : https://github.com/flutter/flutter/issues/19269

我看到人们不喜欢这种方法(功能性小部件/getter 小部件),原因有很多(@Amir Hossein Mirzaei 的回答中描述了一些原因)。

但是,仍然有一些人使用它来编写干净且更少的代码。

我在我的代码中使用它用于:

  1. 不需要自己的上下文并且不依赖于数据更改的小部件。
  2. 分组小部件以进行代码清理。

所以根据我的建议,将功能性小部件用于有限用途并不是一个坏习惯。

getter 当您在一个屏幕中有多个小部件时,小部件很有用。

例如:

class MyScreen extends StatelessWidget{

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Container(
          padding: EdgeInsets.all(81),
          child: contentWidget(),
        )
    );
  }

  Column contentWidget() {
    return Column(
          children: [
            searchWidget(),
            filterwidget(),
            listWidget(
                count: 10
            ),
            addCommentWidget(),
          ],
        );
  }

  Widget searchWidget() { ... return a widget ...}

  Widget filterwidget(){ ... return a widget ... }

  Widget listWidget({int count : 100}){ ... return a widget ... }

  Widget addCommentWidget() { ... return a widget ... }
}

从该代码中,我们知道了我的 statelessWidget 的粗略预览。看看我的 contentWidget() 函数。

另一个好处是我们可以直接从 Android Studio

中的结构面板转到小部件

在我看来,使用函数式小部件比 getter 小部件更好,因为 flutter 小部件总是使用“()”来创建小部件。