【问题标题】:How can i get value from child to parent on button click when button is in parent?当按钮在父项中时,如何在单击按钮时从子项向父项获取价值?
【发布时间】:2020-12-17 00:27:32
【问题描述】:

我一直在使用 Flutter 的 Stepper 视图。当按钮位于父小部件中时,我在单击按钮时从子级向父级获取值时遇到问题。

这是我的父类和我的子类。

父类 这是我的父类,它有一个带有下一步和后退按钮的 Stepper 视图。我想在单击下一步按钮时从我的子类获取父类的值。

   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;
      }
    
    
    }

儿童班 这是我的子类,我有一个类似于单选按钮的 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);
}

【问题讨论】:

    标签: flutter dart callback stepper


    【解决方案1】:

    您可以在下面复制粘贴运行完整代码
    可以使用GlobalKey获取DeliverydeliveryState,使用deliveryState获取Delivery的属性,这里的属性是RadioModel selected
    第 1 步:使用GlobalKey _key = GlobalKey();

    class _MyHomePageState extends State<DeliveryTimeline> {
      ...
      GlobalKey _key = GlobalKey();
    

    第2步:使用deliveryState获取seleted项目

    onStepContinue: () {
              setState(() {
                if (this._currentStep == 0) {
                  this._currentStep = this._currentStep + 1;
    
                  final _DeliveryState deliveryState =
                      _key.currentState;
                  print("hi ${deliveryState.selected.title} ${deliveryState.selected.label} ");
    

    第三步:Delivery需要key

    child: Delivery(
                  key: _key,
                  onShipingTypeClicked: (shippingtype) {
     ...
     Delivery({Key key, this.onShipingTypeClicked}) : super(key:key);
    

    第四步:设置变量selected

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

    【讨论】:

    • 感谢@chunhunghan 真的很有效 拯救我的一天..
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-23
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多