创建一个不是最终的小部件

时间:2019-06-28 19:56:16

标签: flutter

我想知道是否可以声明一个小部件,然后在该小部件中编辑属性。请参见下面的示例:

InputDecoration temp = new InputDecoration(
  labelText: label,
  labelStyle: TextStyle(color: Colors.white),
  // ...
);

然后

temp.suffixIcon = IconButton(icon: Icons.sth);

我似乎无法使其正常工作,因为它返回suffixIcon是最终的。任何帮助表示赞赏。

2 个答案:

答案 0 :(得分:1)

不。这是不可能的(或应尽可能避免)。

原因是,可以将相同的小部件插入小部件树的多个位置。

例如,这样做是完全合理的:

Widget foo = Something();

return Row(
  children: [
    foo,
    foo,
  ]
);

答案 1 :(得分:0)

您要执行的是命令式编程: 您具有程序状态,并且只要它更改,就可以手动更新所有必需的UI元素。

Flutter是一个反应式UI框架。从数学上来说,这意味着存在一些状态 s 和一个构建方法 f ,当状态改变时,框架通过调用函数 f(s)。

更具体地说,您不想更改子窗口小部件的具体属性-您甚至不希望能够执行此操作,因为这违反了响应式范例。而是更改程序的状态,并告诉框架状态已更改。然后它将重新渲染具有新属性的所有子窗口小部件。 不必太担心性能,Flutter在这方面进行了优化。

状态变化的窗口小部件在Flutter中是StatefulWidget个。每个StatefulWidget都有一个对应的State,它也可以包含如下这样的可变(非final)属性:

bool _useFirstIcon = true;

更改状态时,请像这样使用setState中的State函数来通知框架有关更改:

void _changeTheState() {
  setState(() => _useFirstIcon = false);
}

这告诉框架重新渲染该子树。基本上,这意味着您的build方法将在绘制下一帧时被调用。 在那里,您应该根据状态(您的_useFirstIcon属性)返回不同的小部件树。

return SomeWidget(
  decoration: new InputDecoration(
    suffixIcon: IconButton(
      icon: _useFirstIcon ? Icons.someIcon : Icons.someOtherIcon,
      onPressed: _changeTheState,
    ),
  ),
);

请注意,有时您确实希望从父窗口小部件访问窗口小部件的状态。通过为子窗口小部件提供某种controller来实现(可能有些不尽人意),并且子窗口小部件修改了控制器的状态,以使父状态可以访问其自身状态的某些部分。 例如,在TextField中使用TextController使用了这种体系结构。