Flutter:将数据从 StatefulWidget child class 返回给 parent
Flutter: Get data back from StatefulWidget child class to parent
我是 Flutter 新手。
我在应用程序中有一个页面(Stateful Widget),其中一列有很多小部件。为了提高代码的可读性,我采用了一些小部件,并将它们制作成单独的 classes。例如,我将我的下拉菜单小部件制作成它唯一的 class,如下所示:
class DropDownMenuWidget extends StatefulWidget {
DropDownMenuWidget({Key? key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
String dropdownValue = 'One';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
underline: Container(
height: 2,
color: Colors.blue,
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: MASLULIM
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
现在,在父 class 中,我这样显示小部件:
DropDownMenuWidget(),
但是,问题是,当用户单击某个项目时,我只能从 DropDownMenu class 中检索该值,并调用 setState() 方法。但是,我需要在父 class 中读取此值。我怎样才能到达那里?
谢谢
无需在 Widget 中创建 dropdownValue
变量,您可以在 ValueNotifier
的帮助下从父 Widget 获取它,如下所示
class DropDownMenuWidget extends StatefulWidget {
ValueNotifier dropdownValueNotifier;
DropDownMenuWidget(this.dropdownValueNotifier, {Key key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: widget.dropdownValueNotifier,
builder: (context, dropdownValue, _) {
return DropdownButton<String>(
value: dropdownValue,
// ...
onChanged: (String newValue) {
// simply change the value. You dont need setState anymore
widget.dropdownValueNotifier.value = newValue;
},
// ...
);
},
);
}
}
在父Widget中,创建变量并像这样传递它
ValueNotifier dropdownValueNotifier = ValueNotifier('One');
// ...
DropDownMenuWidget(dropdownValueNotifier),
在这种情况下,您可以使用typedef
首先在单独的 DrobDown 菜单中,您可以在 class 之外创建以下图标:
typedef OnItemSelectedDropDown = Function (String value);
现在你可以按如下方式应用这个东西:
class DropDownMenuWidget extends StatefulWidget {
final OnItemSelectedDropDown onItemSelected ;
DropDownMenuWidget({Key? key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
String dropdownValue = 'One';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
underline: Container(
height: 2,
color: Colors.blue,
),
onChanged: (String value) {
//This line return Value
widget.onItemSelected.call(value);
},
items: MASLULIM
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
调用classDropDownMenuWidget
时,在另一屏调用如下:
String dropdownValue ;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DropDown Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'New Value DropDown : $dropdownValue',
),
DropDownMenuWidget(
onItemSelected :(newValue){
setState(() {
dropdownValue = newValue ;
});
}
),
],
),
),
);
}
我是 Flutter 新手。
我在应用程序中有一个页面(Stateful Widget),其中一列有很多小部件。为了提高代码的可读性,我采用了一些小部件,并将它们制作成单独的 classes。例如,我将我的下拉菜单小部件制作成它唯一的 class,如下所示:
class DropDownMenuWidget extends StatefulWidget {
DropDownMenuWidget({Key? key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
String dropdownValue = 'One';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
underline: Container(
height: 2,
color: Colors.blue,
),
onChanged: (String? newValue) {
setState(() {
dropdownValue = newValue!;
});
},
items: MASLULIM
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
现在,在父 class 中,我这样显示小部件:
DropDownMenuWidget(),
但是,问题是,当用户单击某个项目时,我只能从 DropDownMenu class 中检索该值,并调用 setState() 方法。但是,我需要在父 class 中读取此值。我怎样才能到达那里?
谢谢
无需在 Widget 中创建 dropdownValue
变量,您可以在 ValueNotifier
class DropDownMenuWidget extends StatefulWidget {
ValueNotifier dropdownValueNotifier;
DropDownMenuWidget(this.dropdownValueNotifier, {Key key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: widget.dropdownValueNotifier,
builder: (context, dropdownValue, _) {
return DropdownButton<String>(
value: dropdownValue,
// ...
onChanged: (String newValue) {
// simply change the value. You dont need setState anymore
widget.dropdownValueNotifier.value = newValue;
},
// ...
);
},
);
}
}
在父Widget中,创建变量并像这样传递它
ValueNotifier dropdownValueNotifier = ValueNotifier('One');
// ...
DropDownMenuWidget(dropdownValueNotifier),
在这种情况下,您可以使用typedef
首先在单独的 DrobDown 菜单中,您可以在 class 之外创建以下图标:
typedef OnItemSelectedDropDown = Function (String value);
现在你可以按如下方式应用这个东西:
class DropDownMenuWidget extends StatefulWidget {
final OnItemSelectedDropDown onItemSelected ;
DropDownMenuWidget({Key? key}) : super(key: key);
@override
_DropDownMenuWidgetState createState() => _DropDownMenuWidgetState();
}
/// This is the private State class that goes with MyStatefulWidget.
class _DropDownMenuWidgetState extends State<DropDownMenuWidget> {
String dropdownValue = 'One';
@override
Widget build(BuildContext context) {
return DropdownButton<String>(
value: dropdownValue,
icon: Icon(Icons.arrow_downward),
iconSize: 24,
elevation: 16,
style: TextStyle(
color: Colors.black,
fontSize: 20,
),
underline: Container(
height: 2,
color: Colors.blue,
),
onChanged: (String value) {
//This line return Value
widget.onItemSelected.call(value);
},
items: MASLULIM
.map<DropdownMenuItem<String>>((String value) {
return DropdownMenuItem<String>(
value: value,
child: Text(value),
);
}).toList(),
);
}
}
调用classDropDownMenuWidget
时,在另一屏调用如下:
String dropdownValue ;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('DropDown Page'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'New Value DropDown : $dropdownValue',
),
DropDownMenuWidget(
onItemSelected :(newValue){
setState(() {
dropdownValue = newValue ;
});
}
),
],
),
),
);
}