在扑朔迷离中从其父级更改嵌套子级字段?

时间:2019-08-26 15:22:01

标签: flutter

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

编辑:更多详细信息

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

EDIT2-我要实现的目标: 小部件B实际上是一个包含TextFormField和一些其他小部件的容器。我将其用于5个表单字段。现在我想添加一个位置字段。位置字段由B加上在用户输入时打开的列表组成,其中包含Google地理编码的结果。当用户单击结果之一时,我想将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 {

    }
  }
}

1 个答案:

答案 0 :(得分:-1)

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

A(
  child: B(),
);

然后A应该不能能够修改B的状态。即使在技术上可以通过全局变量/ GlobalKey来实现,但这样做是反模式的。

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