【问题标题】:changing a nested child fields from its parent in flutter?在颤动中从其父级更改嵌套的子字段?
【发布时间】:2019-08-26 15:22:01
【问题描述】:

我有一个包含嵌套小部件 B 的小部件 A。当用户单击 A 中的按钮时,我需要更新 B 上的字段(可能通过调用 B 的函数)。我该怎么做?

编辑:更多细节

小部件 B 是我在整个应用程序中使用的小部件,因此我想将其作为单独的小部件。小部件 A 由小部件 B 和另一个按钮组成,我希望单击该按钮将更改小部件 B 内的文本

EDIT2 - 我想要实现的目标: 小部件 B 实际上是一个容器,其中包含 TextFormField 和一些其他小部件。我将它用于 5 个表单域。现在我想为位置添加一个字段。位置字段由 B 和一个在用户输入时打开的列表组成,并且有来自谷歌地理编码的结果。当用户单击其中一个结果时,我想将 TextFormField 控制器文本设置为用户类型的值。 所以,我不想将文本字段的所有逻辑和小部件从 B 复制到 A。

在我的代码小部件中,B 是 FormTextField,A 是 LocationField

class LocationField extends StatefulWidget {
  Location meetingPointData;

    LocationField(this.meetingPointData):  super();

      @override
    _LocationFieldFieldState createState() => new _LocationFieldFieldState();
}



class _LocationFieldFieldState extends State<LocationField>  {

OverlayEntry _overlayEntry;
var addresses;
final LayerLink _layerLink = LayerLink();

  @override
  void initState() {
    super.initState();

  }

  onLocationInputChanged(text) {
    this.findLocations(text);
  }

@override
  Widget build(BuildContext context) {

    return CompositedTransformTarget(
      link: this._layerLink,
      child: FormTextField('meetingPoint', 'Meeting Point', "", "enter the name of a place or an address", TextInputType.text, onLocationInputChanged, true ,  {"empty":  "Please enter the meeting point"})
    );
  }

  OverlayEntry _createOverlayEntry() {

    RenderBox renderBox = context.findRenderObject();
    var size = renderBox.size;

    var addressesWidget =  <Widget>[];
    for(var i=0; i< addresses.length; i++) {
      addressesWidget.add( ListTile(
                    title: Text(addresses[i].addressLine),
                     onTap: () {
                       widget.meetingPointData = Location(addresses[i].addressLine);

                       setState(() {});

                        this._overlayEntry.remove();
                       this._overlayEntry = null;
                    },
                  ),);
    }

   return OverlayEntry(
      builder: (context) => Positioned(
        width: size.width,
        child: CompositedTransformFollower(
          link: this._layerLink,
          showWhenUnlinked: false,
          offset: Offset(10.0, size.height - 45.0),
          child: Material(
            elevation: 4.0,
            child: ListView(
              padding: EdgeInsets.zero,
              shrinkWrap: true,
              children: addressesWidget
            ),
          ),
        ),
      )
    );
  }

  Future findLocations(text) async {
    if(text == "") {
      addresses = [];
      return;
    }
    // From a query
    final query = text;
    try {
          addresses = await Geocoder.local.findAddressesFromQuery(query);
          var first = addresses.first;
          print("${first.featureName} : ${first.coordinates}");
    } catch (err) {

    }

    if(addresses.length > 0) {
      if(this._overlayEntry != null) {
        this._overlayEntry.remove();
        this._overlayEntry = null;
      }
        this._overlayEntry = this._createOverlayEntry();
        Overlay.of(context).insert(this._overlayEntry);

    } else {

    }
  }
}

【问题讨论】:

  • 小部件 B 是 StatefulWidget 吗?可以分享一下代码吗?
  • 为什么B里面的文字不是参数?
  • 文本在 B 中,但它是 B 中复杂容器小部件的一部分。我需要它留在 B 中,但我希望当用户单击 A 中的按钮时,它会更新文本在B

标签: flutter


【解决方案1】:

假设您正在考虑的小部件树是:

A(
  child: B(),
);

那么A应该能够修改B的状态。即使通过全局变量/GlobalKey 在技术上是可行的,但这样做也是反模式。

相反,您应该将状态在树中向上移动,并将您的字段存储在 A 中而不是 B 中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-08-15
    • 2015-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-19
    • 1970-01-01
    相关资源
    最近更新 更多