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

Flutter 我应该使用getter来构建小部件子树吗?,flutter,dart,getter,Flutter,Dart,Getter,今天,我在Flatter中面对新的代码编写风格。通常我使用下一种方法来声明小部件树: 这是我们在创建新的颤振项目后拥有的一个类(为了节省您的时间,我只发布构建方法): @凌驾 小部件构建(构建上下文){ 返回脚手架( appBar:appBar( 标题:文本(widget.title), ), 正文:中( 子:列( mainAxisAlignment:mainAxisAlignment.center, 儿童:[ 正文( “您已经按了这么多次按钮:”, ), 正文( “$”计数器“, 风格:Th

今天,我在Flatter中面对新的代码编写风格。通常我使用下一种方法来声明小部件树:

这是我们在创建新的颤振项目后拥有的一个类(为了节省您的时间,我只发布构建方法):


@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
正文(
“您已经按了这么多次按钮:”,
),
正文(
“$”计数器“,
风格:Theme.of(context).textTheme.headline4,
),
],
),
),
浮动操作按钮:浮动操作按钮(
按下时:\ u递增计数器,
工具提示:“增量”,
子:图标(Icons.add),
),//此尾随逗号使生成方法的自动格式设置更方便。
);
我今天在github的一些Flatter项目中看到的区别是,将小部件声明为getter:


  @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,
    );

@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(widget.title),
),
正文:中(
子:列(
mainAxisAlignment:mainAxisAlignment.center,
儿童:[
文本推送,
反文本,
],
),
),
浮动操作按钮:浮动操作按钮(
按下时:\ u递增计数器,
工具提示:“增量”,
子:图标(Icons.add),
),//此尾随逗号使生成方法的自动格式设置更方便。
);
}
小部件得到文本推送{
返回文本(
“您已经按了这么多次按钮:”,
);
}
小部件获取计数器文本{
返回文本(
“$”计数器“,
风格:Theme.of(context).textTheme.headline4,
);

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

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

这是一种不好的做法,因为:

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

  • 当您为一个小部件创建一个单独的类时,您可以选择以多种方式对其进行重构,例如使其成为有状态或无状态,而无需任何麻烦

  • 当您在一个单独的类中定义一个小部件时,很难进行调试,您将为它命名,并且很容易在小部件树中跟踪该小部件并进行调试

  • 还有很多其他的事情,所描述的方法类似于反应中的功能组件。在一些优秀的程序员参与的Flatters GitHub页面中对此进行了很好的讨论。您可以看到,有关此主题的更多知识,请参见以下链接:

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

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

    我在代码中使用它用于:

  • 小部件,不需要自己的上下文,也不依赖于数据更改
  • 为代码清理对小部件进行分组

  • 因此,根据我的建议,在有限的范围内使用功能性小部件并不是一个坏习惯。

    当您在一个屏幕中有多个小部件时,getter for widget是有用的

    例如:

    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 ... }
    }
    
    从这些代码中,我们知道了无状态小部件的大致预览

    另一个好处是,我们可以直接从Android Studio的结构面板访问小部件


    在我看来,使用功能性小部件比getter小部件更好,因为flatter小部件总是使用“()”来创建小部件。

    使用getter会破坏“可重用代码”的整个概念。通过使用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 ... }
    }