访问子小部件状态属性

时间:2020-04-15 09:45:52

标签: flutter

我有一个名为AddItemPage的屏幕,该屏幕在build方法中调用QtyWidget。因此,在AddItemPage内部,如何访问QtyWidget状态的_itemCount

itempage.dart

    import 'package:flutter/material.dart';
    import 'widget/options/qty_widget.dart';
    import 'widget/options/option_widget.dart';
    import 'package:provider/provider.dart';
    import '../session/data.dart';
    import '../cart/cart.dart';

    class AddItemPage extends StatefulWidget {
      final String title = 'Add';

      final dynamic data;
      final dynamic itemOption;

      AddItemPage(this.data, this.itemOption);

      @override
      State<StatefulWidget> createState() => AddItemPageState();
    }

    class AddItemPageState extends State<AddItemPage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            backgroundColor: Colors.amber[800],
            title: Text(widget.title,
                style: TextStyle(color: Colors.amberAccent[800])),
          ),
          body: Builder(builder: (BuildContext context) {

            List<Widget> listWidget = <Widget>[];

            if (widget.data.containsKey('image')) {
              String imagePath = "assets/images/lobster_tray.png";
              listWidget.add(
                Container(
                  height: 150,
                    decoration: BoxDecoration(
                        image: DecorationImage(
                            image: AssetImage(imagePath),
                            fit: BoxFit.cover)),
                    width: double.infinity,
                  ),);
            }
            listWidget.addAll([
              Center(
                child: Text(widget.data['dish'],
                  textAlign: TextAlign.left,
                  style: TextStyle(
                    height: 2,
                    fontSize: 20,
                    color: Colors.black,

                  )),
              ),
              Center(
                child: Text(widget.data['description'],
                    textAlign: TextAlign.left,
                    style: TextStyle(
                      height: 2,
                      fontWeight: FontWeight.normal,
                      fontSize: 14,
                      color: Colors.black,
                    )),
              ),
              Center(
                child: Text('\$' + widget.data['price'],
                    textAlign: TextAlign.left,
                    style: TextStyle(
                      height: 2,
                      fontWeight: FontWeight.normal,
                      fontSize: 14,
                      color: Colors.red,
                    )),
              ),
              Container(
                height: 20,
              ),

            ]);


            //option
            List<Widget> optionList = [];

            StatefulWidget qtyWidget = QtyWidget();
            optionList.add(qtyWidget);
            optionList.add(Container(height: 15));

            if (widget.data.containsKey('option')) {
              for (String optionKey in widget.data['option']) {
                dynamic optionData = widget.itemOption[optionKey];
                optionList.add(ItemOptionWidget(optionData));
                optionList.add(Container(height: 15));
              }
            }

            listWidget.add(
                Container(
                  padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
                  child: Column(
                  children: optionList,
              ),
                )
            );
            optionList.add(Container(height: 10));

            //button
            listWidget.add(Center(
              child: Container(
                child: Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Container(
                        alignment: Alignment.center,
                        child: RaisedButton(
                          onPressed: () {
                            Provider.of<PData>(context, listen: false)
                                .addItemToCart(widget.data);
                            Navigator.push(
                                context,
                                MaterialPageRoute(
                                    builder: (context) => CartPage()));
                          },
                          color: Colors.amber[800],
                          child: const Text('Add to Order'),
                        ),
                      ),
                      Container(
                        margin: EdgeInsets.fromLTRB(10, 0, 0, 0),
                        alignment: Alignment.center,
                        child: RaisedButton(
                          onPressed: () async {
                            Navigator.pop(context, true);
                          },
                          color: Colors.grey[200],
                          child: const Text('Cancel'),
                        ),
                      ),
                    ]),
              ),
            ));

            return ListView(
              children: listWidget,
            );
          }),
        );
      }
    }

qty_widget.dart

import 'package:flutter/material.dart';

class QtyWidget extends StatefulWidget {
  String title;
  QtyWidget({this.title});
  @override
  _QtyWidgetState createState() => new _QtyWidgetState();
}

class _QtyWidgetState extends State<QtyWidget> {
  int _itemCount = 1;
  @override
  Widget build(BuildContext context) {
    return Column(
        children: <Widget>[
          Center(
            child: Text(
              'Qty',
              style: TextStyle(
                  fontWeight: FontWeight.normal,
                  fontSize: 14,
                  color: Colors.grey[400]),
            ),
          ),
          Container(
            height: 5,
          ),
          Container(
            decoration: BoxDecoration(
                color: Colors.white,
                border: Border.all(
                  color: Colors.grey[400],
                ),
                borderRadius: BorderRadius.all(Radius.circular(5))
            ),
            child: Row(
              mainAxisAlignment: MainAxisAlignment.center,
              crossAxisAlignment: CrossAxisAlignment.center,
              children: <Widget>[
                IconButton(icon: new Icon(Icons.remove),
                    color: Colors.grey[400],
                    onPressed: () {
                      setState(() {
                        if (_itemCount >=2 ) {
                          _itemCount = _itemCount - 1 ;
                        }
                      });

                    }),
                Text(_itemCount.toString()),
                IconButton(icon: new Icon(Icons.add),
                    color: Colors.grey[400],
                    onPressed: ()=>setState(()=>_itemCount++))
              ],
            ),
          ),
        ]);

  }
}

1 个答案:

答案 0 :(得分:0)

您可以在下面复制粘贴运行完整代码
步骤1:在QtyWidget中初始化initState()并传递refresh()回调

 QtyWidget qtyWidget;

  void refresh() {
    setState(() {});
  }

 @override
  void initState() {
    qtyWidget = QtyWidget(
      callback: refresh,
    );

步骤2:将itemCount移至QtyWidget

class QtyWidget extends StatefulWidget {
  String title;
  int itemCount = 1;
  VoidCallback callback;
  QtyWidget({this.title, this.callback});   

第3步:像这样QtyWidget进入qtyWidget.itemCount

listWidget.add(Center(child: Text(qtyWidget.itemCount.toString())));

listWidget.add(
        Center(child: Text((optionList[0] as QtyWidget).itemCount.toString())));  

步骤4:在_QtyWidgetState中,用widget.itemCountwidget.callback()

执行
onPressed: () {
                  setState(() {
                    if (widget.itemCount >= 2) {
                      widget.itemCount = widget.itemCount - 1;
                    }
                  });
                  widget.callback();
                }),

工作演示

enter image description here

完整代码

import 'package:flutter/material.dart';

class AddItemPage extends StatefulWidget {
  final String title = 'Add';

  final dynamic data;
  final dynamic itemOption;

  AddItemPage(this.data, this.itemOption);

  @override
  State<StatefulWidget> createState() => AddItemPageState();
}

class AddItemPageState extends State<AddItemPage> {
  List<Widget> listWidget;
  QtyWidget qtyWidget;

  void refresh() {
    setState(() {});
  }

  void handleListWidget() {
    listWidget = <Widget>[];

    if (widget.data.containsKey('image')) {
      String imagePath = "assets/images/lobster_tray.png";
      listWidget.add(
        Container(
          height: 150,
          decoration: BoxDecoration(
              image: DecorationImage(
                  image: AssetImage(imagePath), fit: BoxFit.cover)),
          width: double.infinity,
        ),
      );
    }
    listWidget.addAll([
      Center(
        child: Text(widget.data['dish'],
            textAlign: TextAlign.left,
            style: TextStyle(
              height: 2,
              fontSize: 20,
              color: Colors.black,
            )),
      ),
      Center(
        child: Text(widget.data['description'],
            textAlign: TextAlign.left,
            style: TextStyle(
              height: 2,
              fontWeight: FontWeight.normal,
              fontSize: 14,
              color: Colors.black,
            )),
      ),
      Center(
        child: Text('\$' + widget.data['price'],
            textAlign: TextAlign.left,
            style: TextStyle(
              height: 2,
              fontWeight: FontWeight.normal,
              fontSize: 14,
              color: Colors.red,
            )),
      ),
      Container(
        height: 20,
      ),
    ]);

    //option
    List<Widget> optionList = [];

    optionList.add(qtyWidget);
    optionList.add(Container(height: 15));

    if (widget.data.containsKey('option')) {
      for (String optionKey in widget.data['option']) {
        dynamic optionData = widget.itemOption[optionKey];
        //optionList.add(ItemOptionWidget(optionData));
        optionList.add(Container(height: 15));
      }
    }

    listWidget.add(Container(
      padding: EdgeInsets.fromLTRB(15, 0, 15, 0),
      child: Column(
        children: optionList,
      ),
    ));
    optionList.add(Container(height: 10));

    //button
    listWidget.add(Center(
      child: Container(
        child:
            Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
          Container(
            alignment: Alignment.center,
            child: RaisedButton(
              onPressed: () {
                /* Provider.of<PData>(context, listen: false)
                            .addItemToCart(widget.data);
                        Navigator.push(
                            context,
                            MaterialPageRoute(
                                builder: (context) => CartPage()));*/
              },
              color: Colors.amber[800],
              child: const Text('Add to Order'),
            ),
          ),
          Container(
            margin: EdgeInsets.fromLTRB(10, 0, 0, 0),
            alignment: Alignment.center,
            child: RaisedButton(
              onPressed: () async {
                Navigator.pop(context, true);
              },
              color: Colors.grey[200],
              child: const Text('Cancel'),
            ),
          ),
        ]),
      ),
    ));

    listWidget.add(Center(child: Text(qtyWidget.itemCount.toString())));

    listWidget.add(
        Center(child: Text((optionList[0] as QtyWidget).itemCount.toString())));
  }

  @override
  void initState() {
    qtyWidget = QtyWidget(
      callback: refresh,
    );

    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Colors.amber[800],
        title: Text(widget.title,
            style: TextStyle(color: Colors.amberAccent[800])),
      ),
      body: Builder(builder: (BuildContext context) {
        print("build");
        print(qtyWidget.itemCount.toString());
        handleListWidget();
        return ListView(
          children: listWidget,
        );
      }),
    );
  }
}

class QtyWidget extends StatefulWidget {
  String title;
  int itemCount = 1;
  VoidCallback callback;
  QtyWidget({this.title, this.callback});
  @override
  _QtyWidgetState createState() => new _QtyWidgetState();
}

class _QtyWidgetState extends State<QtyWidget> {
  //int _itemCount = 1;
  @override
  Widget build(BuildContext context) {
    return Column(children: <Widget>[
      Center(
        child: Text(
          'Qty',
          style: TextStyle(
              fontWeight: FontWeight.normal,
              fontSize: 14,
              color: Colors.grey[400]),
        ),
      ),
      Container(
        height: 5,
      ),
      Container(
        decoration: BoxDecoration(
            color: Colors.white,
            border: Border.all(
              color: Colors.grey[400],
            ),
            borderRadius: BorderRadius.all(Radius.circular(5))),
        child: Row(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            IconButton(
                icon: new Icon(Icons.remove),
                color: Colors.grey[400],
                onPressed: () {
                  setState(() {
                    if (widget.itemCount >= 2) {
                      widget.itemCount = widget.itemCount - 1;
                    }
                  });
                  widget.callback();
                }),
            Text(widget.itemCount.toString()),
            IconButton(
                icon: new Icon(Icons.add),
                color: Colors.grey[400],
                onPressed: () {
                  setState(() => widget.itemCount++);
                  widget.callback();
                })
          ],
        ),
      ),
    ]);
  }
}

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:
          AddItemPage({"dish": "a", "price": "123", "description": "test"}, {}),
    );
  }
}