Flutter 当按钮位于父级时,如何在单击按钮时从子级到父级获取值?

Flutter 当按钮位于父级时,如何在单击按钮时从子级到父级获取值?,flutter,dart,callback,stepper,Flutter,Dart,Callback,Stepper,我一直在使用Flatter的Stepper view,我在点击按钮时遇到了一个问题,因为按钮在父窗口小部件中 这是我的父班和子班 父类 这是我的父类,它有一个带有“下一步”和“上一步”按钮的步进视图。单击“下一步”按钮时,我想从我的子类到父类获取值 class DeliveryTimeline extends StatefulWidget { DeliveryTimeline({Key key, this.title}) : super(key: key);

我一直在使用Flatter的Stepper view,我在点击按钮时遇到了一个问题,因为按钮在父窗口小部件中

这是我的父班和子班

父类 这是我的父类,它有一个带有“下一步”和“上一步”按钮的步进视图。单击“下一步”按钮时,我想从我的子类到父类获取值

   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(),
    );
  }
}