【问题标题】:What is the 'state' of widgets outside of a class类之外的小部件的“状态”是什么
【发布时间】:2019-01-31 16:06:32
【问题描述】:

我已经开始使用 Flutter 进行一些工作,我对类之外的小部件的“状态”感到好奇。当我将searchAndAddRow 移到myApp 类内部的构建函数之外时,我需要将Widget 声明为final,这是有道理的,因为它是一个无状态类。当我将 Widget 完全移出一个类时(就像我在代码 sn-p 中所做的那样),我不需要定义任何东西。

在这两种情况下,当我将searchAndAddRow 移到MyAppbuild 之外时,android studio 中的“热重载”功能不起作用,应用程序需要停止并重新启动才能使更改生效。哪一点促使我首先提出这个问题。

import 'package:flutter/material.dart';

void main() => runApp(new MyApp());

Widget searchAndAddRow = Container(
  padding: const EdgeInsets.all(0.0),
  child: Row(
    children: [
      Icon(const IconData(0xe8b6, fontFamily: 'MaterialIcons')),
      new Container(
        width: 80.0,
        child: TextField(
          decoration: new InputDecoration(
              border: const UnderlineInputBorder(), hintText: 'search'),
        ),
      ),
      new Expanded(
        child: new Row(mainAxisAlignment: MainAxisAlignment.end, children: [
          new IconButton(
            icon: new Icon(const IconData(0xe148, fontFamily: 'MaterialIcons')),
            tooltip: 'Add a new item!',
            onPressed: null,
          ),
        ]),
      )
    ],
  ),
);

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Material App Title', // App title
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: Scaffold(
          appBar: AppBar(
            title: Text('App Bar Title (Home)'),
          ),
          body: ListView(
            children: [
              //Row 1 contains: Search and Add
              searchAndAddRow
              //Row 2 contains: List
              //Row 3 contains: Sort dropdown
            ],
          )
       ),
    );
  }
}

【问题讨论】:

    标签: dart flutter


    【解决方案1】:

    您的问题是,您没有定义小部件。您定义了一个变量。

    变量不会热重载,因为框架无法知道您是要使用旧值还是新值。

    一般情况下,不要将小部件树提取到变量中。而是将它们提取到另一个小部件中:

    /** DON"T */
    Widget foo = Container();
    
    /** DO */
    
    class Foo extends StatelessWidget {
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    

    但如果它是恒定的呢?出于优化目的

    好吧,你可以为你的小部件定义一个const 构造函数:

    class Foo extends StatelessWidget {
      const Foo();
    
      @override
      Widget build(BuildContext context) {
        return Container();
      }
    }
    

    这意味着无论何时你执行const Foo()const 关键字自 dart 2.0 起不再需要),它总是会返回完全相同的小部件实例。

    基本上,它的作用与将其提取到常量变量中一样。但隐含地,因此热重载仍然有效。

    【讨论】:

      【解决方案2】:

      这帮助我理解了为什么应该将小部件提取到另一个小部件中的原理,以及为什么这里为每个有状态小部件设置单独的状态: Why are stateful widgets defined as two classes in flutter?

      主要思想是将小部件对象保存在静态树中,在构造函数中定义它们的 UI 属性(例如,TextStyle、颜色、子项)。像 HTML DOM 一样,有状态的是一个 div 容器,您可以在其中放置一些状态

      【讨论】:

        猜你喜欢
        • 2019-12-17
        • 1970-01-01
        • 1970-01-01
        • 2018-05-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多