我有一个具有嵌套小部件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 {
}
}
}
答案 0 :(得分:-1)
假设您要考虑的小部件树是:
A(
child: B(),
);
然后A
应该不能能够修改B
的状态。即使在技术上可以通过全局变量/ GlobalKey来实现,但这样做是反模式的。
相反,您应该将状态上移到树中,并将字段存储在A而不是B中。