Flutter 当按钮位于父级时,如何在单击按钮时从子级到父级获取值?
我一直在使用Flatter的Stepper view,我在点击按钮时遇到了一个问题,因为按钮在父窗口小部件中 这是我的父班和子班 父类 这是我的父类,它有一个带有“下一步”和“上一步”按钮的步进视图。单击“下一步”按钮时,我想从我的子类到父类获取值Flutter 当按钮位于父级时,如何在单击按钮时从子级到父级获取值?,flutter,dart,callback,stepper,Flutter,Dart,Callback,Stepper,我一直在使用Flatter的Stepper view,我在点击按钮时遇到了一个问题,因为按钮在父窗口小部件中 这是我的父班和子班 父类 这是我的父类,它有一个带有“下一步”和“上一步”按钮的步进视图。单击“下一步”按钮时,我想从我的子类到父类获取值 class DeliveryTimeline extends StatefulWidget { DeliveryTimeline({Key key, this.title}) : super(key: key);
class DeliveryTimeline extends StatefulWidget {
DeliveryTimeline({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<DeliveryTimeline> {
int _currentStep = 0;
String shippingtype;
@override
Widget build(BuildContext context) {
return new Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
iconTheme: new IconThemeData(color: Colors.black),
elevation: 0,
title: Text(
"Checkout",
style: TextStyle(color: Colors.black),
),
),
body: Stepper(
type: StepperType.horizontal,
steps: _mySteps(),
currentStep: this._currentStep,
onStepTapped: (step) {
setState(() {
this._currentStep = step;
});
},
onStepContinue: () {
setState(() {
if (this._currentStep == 0) {
this._currentStep = this._currentStep + 1;
**//need to get value here on first next click**
} else if (this._currentStep == 1) {
this._currentStep = this._currentStep + 1;
} else {
print('Completed, check fields.');
}
});
},
onStepCancel: () {
setState(() {
if (this._currentStep > 0) {
this._currentStep = this._currentStep - 1;
} else {
this._currentStep = 0;
}
});
},
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue,
VoidCallback onStepCancel,
Function onShippingNextClick}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
OutlineButton(
child: new Text("Back"),
onPressed: onStepCancel,
shape: new RoundedRectangleBorder(
borderRadius: new BorderRadius.circular(4.0))),
MaterialButton(
child: Text("Next"),
color: AppColors.primarycolor,
textColor: Colors.white,
onPressed: onStepContinue,
),
],
);
}));
}
List<Step> _mySteps() {
List<Step> _steps = [
Step(
title: Text('Delivery'),
content: Center(
child: Container(
height: MediaQuery.of(context).size.height / 1.5,
child: Delivery(onShipingTypeClicked: (shippingtype){
shippingtype = shippingtype;
print("myvalue${shippingtype}");
},),
),
),
isActive: _currentStep >= 0,
),
Step(
title: Text('Address'),
content: Address(),
isActive: _currentStep >= 1,
),
Step(
title: Text('Payment'),
content: Payment(),
isActive: _currentStep >= 2,
)
];
return _steps;
}
}
class DeliveryTimeline扩展StatefulWidget{
DeliveryTimeline({Key,this.title}):super(Key:Key);
最后的字符串标题;
@凌驾
_MyHomePageState createState()=>new_MyHomePageState();
}
类_MyHomePageState扩展状态{
int _currentStep=0;
串装式;
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:appBar(
背景颜色:Colors.white,
标题:对,
iconTheme:new IconThemeData(颜色:Colors.black),
海拔:0,
标题:正文(
“结帐”,
样式:TextStyle(颜色:Colors.black),
),
),
机身:步进电机(
类型:StepperType.horizontal,
步骤:_mySteps(),
currentStep:此。\ u currentStep,
步骤:(步骤){
设置状态(){
这是。_currentStep=步骤;
});
},
onStepContinue:(){
设置状态(){
如果(此._currentStep==0){
此。_currentStep=此。_currentStep+1;
**//需要在第一次下一次单击时在此处获取值**
}else if(此._currentStep==1){
此。_currentStep=此。_currentStep+1;
}否则{
打印('已完成,检查字段');
}
});
},
onStepCancel:(){
设置状态(){
如果(此._currentStep>0){
此._currentStep=此._currentStep-1;
}否则{
这一点。_currentStep=0;
}
});
},
controlsBuilder:(BuildContext上下文,
{VoidCallback onStepContinue,
VoidCallback onStepCancel,
函数onShippingNextClick}){
返回行(
mainAxisAlignment:mainAxisAlignment.spaceBetween,
儿童:[
大纲按钮(
子项:新文本(“返回”),
onPressed:onStepCancel,
形状:新的RoundedRectangleBorder(
borderRadius:新的borderRadius.circular(4.0)),
材料按钮(
子项:文本(“下一个”),
颜色:AppColors.primarycolor,
textColor:Colors.white,
onPressed:onStepContinue,
),
],
);
}));
}
列表_mySteps(){
列表_步骤=[
台阶(
标题:文本(“交付”),
内容:中心(
子:容器(
高度:MediaQuery.of(context).size.height/1.5,
子项:交付(OnShippingTypeClicked:(shippingtype){
shippingtype=shippingtype;
打印(“myvalue${shippingtype}”);
},),
),
),
isActive:_currentStep>=0,
),
台阶(
标题:文本(“地址”),
内容:地址(),
isActive:_currentStep>=1,
),
台阶(
标题:文本(“付款”),
内容:付款(),
isActive:_currentStep>=2,
)
];
返回步骤;
}
}
儿童班
这是我的子类我有一个类似单选按钮的Listview。单击按钮时,我希望所选项目及其值显示在父类中
class Delivery extends StatefulWidget {
final ValueChanged<String> onShipingTypeClicked;
Delivery({this.onShipingTypeClicked});
@override
_DeliveryState createState() => _DeliveryState();
}
class _DeliveryState extends State<Delivery> {
List<RadioModel> sampleData = new List<RadioModel>();
@override
void initState() {
// TODO: implement initState
super.initState();
sampleData.add(new RadioModel(false, 'A', 0xffe6194B, "Standard Delivery",
"Order will be delivered between 3 - 5 business days", 1));
sampleData.add(new RadioModel(
true,
'A',
0xffe6194B,
"Next Day Delivery",
"Place your order before 6pm and your items will be delivered the next day",
2));
sampleData.add(new RadioModel(
false,
'A',
0xffe6194B,
"Nominated Delivery",
"Pick a particular date from the calendar and order will be delivered on selected date",
3));
}
@override
Widget build(BuildContext context) {
return new Scaffold(
body: new ListView.builder(
itemCount: sampleData.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return new InkWell(
onTap: () {
setState(() {
sampleData.forEach((element) => element.isSelected = false);
sampleData[index].isSelected = true;
widget.onShipingTypeClicked(sampleData[index].buttonText);
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
TextSmallTitleSize(
title: sampleData[index].title,
),
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Flexible(
child: TextSmallDimText(sampleData[index].label),
),
RadioItem(sampleData[index]),
],
),
)
],
));
},
),
);
}
}
class RadioItem extends StatelessWidget {
final RadioModel _item;
RadioItem(this._item);
@override
Widget build(BuildContext context) {
return new Container(
margin: new EdgeInsets.all(15.0),
child: new Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
new Container(
height: 25.0,
width: 25.0,
alignment: Alignment.center,
child: Container(
height: 15.0,
width: 15.0,
decoration: new BoxDecoration(
color: AppColors.primarycolor,
borderRadius:
const BorderRadius.all(const Radius.circular(15)),
)),
decoration: new BoxDecoration(
color: Colors.transparent,
border: new Border.all(
width: 3.0,
color: _item.isSelected
? AppColors.primarycolor
: Colors.transparent),
borderRadius: const BorderRadius.all(const Radius.circular(25)),
),
),
new Container(margin: new EdgeInsets.only(left: 10.0))
],
),
);
}
}
class RadioModel {
bool isSelected;
final String buttonText;
final int colorCode;
final String title, label;
final int buttonid;
RadioModel(this.isSelected, this.buttonText, this.colorCode, this.title,
this.label, this.buttonid);
}
类传递扩展了StatefulWidget{
装运时更改的最终值单击;
传递({this.onShipingTypeClicked});
@凌驾
_DeliveryState createState();
}
类_DeliveryState扩展状态{
List sampleData=新列表();
@凌驾
void initState(){
//TODO:实现initState
super.initState();
sampleData.add(新RadioModel(假'A',0xffe6194B,“标准交付”),
“订单将在3-5个工作日内送达”,1);
sampleData.add(新RadioModel(
是的,
“A”,
0xffe6194B,
“次日送达”,
“在下午6点之前下单,您的物品将在第二天送达”,
2));
sampleData.add(新RadioModel(
假,,
“A”,
0xffe6194B,
“指定交付”,
“从日历中选择特定日期,订单将在所选日期交付”,
3));
}
@凌驾
小部件构建(构建上下文){
归还新脚手架(
正文:新建ListView.builder(
itemCount:sampleData.length,
收缩膜:对,
物理学:NeverscrollableScroll物理学(),
itemBuilder:(构建上下文,int索引){
返回新墨水池(
onTap:(){
设置状态(){
sampleData.forEach((element)=>element.isSelected=false);
sampleData[index].isSelected=true;
widget.OnShippingTypeClicked(sampleData[index].buttonText);
});
},
子:列(
class _MyHomePageState extends State<DeliveryTimeline> {
...
GlobalKey _key = GlobalKey();
onStepContinue: () {
setState(() {
if (this._currentStep == 0) {
this._currentStep = this._currentStep + 1;
final _DeliveryState deliveryState =
_key.currentState;
print("hi ${deliveryState.selected.title} ${deliveryState.selected.label} ");
child: Delivery(
key: _key,
onShipingTypeClicked: (shippingtype) {
...
Delivery({Key key, this.onShipingTypeClicked}) : super(key:key);
RadioModel selected = null;
...
return InkWell(
onTap: () {
setState(() {
...
selected = sampleData[index];
I/flutter ( 6246): hi Standard Delivery Order will be delivered between 3 - 5 business days
import 'package:flutter/material.dart';
class DeliveryTimeline extends StatefulWidget {
DeliveryTimeline({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<DeliveryTimeline> {
int _currentStep = 0;
String shippingtype;
GlobalKey _key = GlobalKey();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Colors.white,
centerTitle: true,
iconTheme: IconThemeData(color: Colors.black),
elevation: 0,
title: Text(
"Checkout",
style: TextStyle(color: Colors.black),
),
),
body: Stepper(
type: StepperType.horizontal,
steps: _mySteps(),
currentStep: this._currentStep,
onStepTapped: (step) {
setState(() {
this._currentStep = step;
});
},
onStepContinue: () {
setState(() {
if (this._currentStep == 0) {
this._currentStep = this._currentStep + 1;
final _DeliveryState deliveryState =
_key.currentState;
print("hi ${deliveryState.selected.title} ${deliveryState.selected.label} ");
} else if (this._currentStep == 1) {
this._currentStep = this._currentStep + 1;
} else {
print('Completed, check fields.');
}
});
},
onStepCancel: () {
setState(() {
if (this._currentStep > 0) {
this._currentStep = this._currentStep - 1;
} else {
this._currentStep = 0;
}
});
},
controlsBuilder: (BuildContext context,
{VoidCallback onStepContinue,
VoidCallback onStepCancel,
Function onShippingNextClick}) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
OutlineButton(
child: Text("Back"),
onPressed: onStepCancel,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(4.0))),
MaterialButton(
child: Text("Next"),
color: Colors.blue,
textColor: Colors.white,
onPressed: onStepContinue,
),
],
);
}));
}
List<Step> _mySteps() {
List<Step> _steps = [
Step(
title: Text('Delivery'),
content: Center(
child: Container(
height: MediaQuery.of(context).size.height / 1.5,
child: Delivery(
key: _key,
onShipingTypeClicked: (shippingtype) {
shippingtype = shippingtype;
print("myvalue${shippingtype}");
},
),
),
),
isActive: _currentStep >= 0,
),
Step(
title: Text('Address'),
content: Text("Address()"),
isActive: _currentStep >= 1,
),
Step(
title: Text('Payment'),
content: Text("Payment()"),
isActive: _currentStep >= 2,
)
];
return _steps;
}
}
class Delivery extends StatefulWidget {
final ValueChanged<String> onShipingTypeClicked;
Delivery({Key key, this.onShipingTypeClicked}) : super(key:key);
@override
_DeliveryState createState() => _DeliveryState();
}
class _DeliveryState extends State<Delivery> {
List<RadioModel> sampleData = List<RadioModel>();
@override
void initState() {
// TODO: implement initState
super.initState();
sampleData.add(RadioModel(false, 'A', 0xffe6194B, "Standard Delivery",
"Order will be delivered between 3 - 5 business days", 1));
sampleData.add(RadioModel(
true,
'A',
0xffe6194B,
"Next Day Delivery",
"Place your order before 6pm and your items will be delivered the next day",
2));
sampleData.add(RadioModel(
false,
'A',
0xffe6194B,
"Nominated Delivery",
"Pick a particular date from the calendar and order will be delivered on selected date",
3));
}
RadioModel selected = null;
@override
Widget build(BuildContext context) {
return Scaffold(
body: ListView.builder(
itemCount: sampleData.length,
shrinkWrap: true,
physics: NeverScrollableScrollPhysics(),
itemBuilder: (BuildContext context, int index) {
return InkWell(
onTap: () {
setState(() {
sampleData.forEach((element) => element.isSelected = false);
sampleData[index].isSelected = true;
selected = sampleData[index];
widget.onShipingTypeClicked(sampleData[index].buttonText);
});
},
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
ListTile(
title: Text(sampleData[index].title),
),
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Flexible(
child: Text(sampleData[index].label),
),
RadioItem(sampleData[index]),
],
),
)
],
));
},
),
);
}
}
class RadioItem extends StatelessWidget {
final RadioModel _item;
RadioItem(this._item);
@override
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.all(15.0),
child: Row(
mainAxisSize: MainAxisSize.max,
children: <Widget>[
Container(
height: 25.0,
width: 25.0,
alignment: Alignment.center,
child: Container(
height: 15.0,
width: 15.0,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius:
const BorderRadius.all(const Radius.circular(15)),
)),
decoration: BoxDecoration(
color: Colors.transparent,
border: Border.all(
width: 3.0,
color: _item.isSelected ? Colors.blue : Colors.transparent),
borderRadius: const BorderRadius.all(const Radius.circular(25)),
),
),
Container(margin: EdgeInsets.only(left: 10.0))
],
),
);
}
}
class RadioModel {
bool isSelected;
final String buttonText;
final int colorCode;
final String title, label;
final int buttonid;
RadioModel(this.isSelected, this.buttonText, this.colorCode, this.title,
this.label, this.buttonid);
}
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: DeliveryTimeline(),
);
}
}