Flutter-子类小部件与包装它

时间:2018-08-13 12:56:45

标签: flutter

我有一些类似于下面的代码:

class InputWithValidation extends StatelessWidget {
  InputWithValidation({this.fieldName, this.accessor});

  final String fieldName;
  final ModelAccessor accessor;

  Widget build(context) {

    var elem = FooDataDictionary.of(context).dataElement(fieldName);

    return Container(
        margin: EdgeInsets.all(inputMargin),
        child: TextFormField(
          keyboardType: elem.keyboardType,
          initialValue: elem.getAsString(accessor),
          autovalidate: true,
          validator: elem.validate,
          onSaved: (val) {
            elem.setFromString(accessor, val);
          },
          decoration: InputDecoration(
            hintText: FooLocalizations.of(context).hint(fieldName),
            labelText: FooLocalizations.of(context).label(fieldName)),
        ));
  }
}

我想重构它以提取TextFormField,这样我就可以在其他地方重用它,而无需对边距的使用进行硬编码。

我的第一个尝试是写:

class DataElementTextFormField extends TextFormField
{
  final DataElement dataElement;
  final ModelAccessor accessor;

  DataElementTextFormField(this.dataElement, this.accessor) :
      super(
        keyboardType: dataElement.keyboardType,
        initialValue: dataElement.getAsString(accessor),
        autovalidate: true,
        validator: dataElement.validate,
        onSaved: (val) {
          dataElement.setFromString(accessor, val);
        },
        decoration: InputDecoration(
          hintText: FooLocalizations.of(context).hint(fieldName),
          labelText: FooLocalizations.of(context).label(fieldName)),
      );
}

但是hintText / labelText行不再起作用,因为它们需要BuildContext来获取正确的本地化实例。我暂时感到困惑,因为我不确定像这样子化小部件的正确方法。

所以我的问题有两个方面:

  1. StatefulWidget子类化并允许访问BuildContext的正确方法是什么?
  2. 鉴于我在#1方面苦苦挣扎,简单地包装小部件以添加其他功能还是将它们子类化会更好吗?什么是“最佳实践”?

1 个答案:

答案 0 :(得分:1)

通常,即使对于SDK的小部件,组合优先于继承。如果继承,则确实需要深入研究父类,并确保遵守所有协议。使用composition,您可以简单地查看已发布的API,并遵循其中的规则。