【问题标题】:How to pass data from one widget to its sibling widget?如何将数据从一个小部件传递到其兄弟小部件?
【发布时间】:2019-10-16 16:56:21
【问题描述】:

我有一个 Column 小部件,其中包含一个自定义小部件 (ViewCard) 和一个 RaisedButton。 ViewCard 中有一些数据可供用户交互和更改。现在,我希望 RaisedButton 将这些更改或详细信息提交到 Firestore。我现在面临的问题是我无法从外部访问自定义小部件的数据。

Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: <Widget>[
          SizedBox(height: 20,),

          ViewCard(args.combo,_changeprice),

          SizedBox(height: 20,),

          Container(
            padding: EdgeInsets.only(top: 15),
            height: 75,
            decoration: BoxDecoration(
              color: Colors.yellow,
              borderRadius: BorderRadius.circular(20)
            ),
            child: Card(
              elevation: 0,
              color: Colors.transparent,
              child: Row(
                children: <Widget>[
                Text("Cart price : $price"),
                SizedBox(width: 75,),
                Container(
                  decoration: BoxDecoration(
                    borderRadius: BorderRadius.circular(25),
                    color: Colors.yellow
                  ),
                  child: RaisedButton(
                    onPressed: (){},     
                    child: Text("Host this order"),
                  ),
                ),
              ],)
            ),
          )
        ],
      ),

我需要以某种方式将 CardView 内部的 3 个变量传递给当前类,以便我可以在 RaisedButton 中使用它们。

edit : args.combo 是 Combo 类型

class Combo {
  List<Items> items;
  Combo({this.items});
}
class Items {
  String item;
  String price;
}

这是 CardView 的代码。此类为 args.combo 创建了一张卡片

class ViewCard extends StatefulWidget {
  ViewCard(this.combo, this.changePrice);
  final Combo combo;
  final IntCallback changePrice;

  @override
  _ViewCardState createState() => _ViewCardState();
}

class _ViewCardState extends State<ViewCard> {
  @override
  Widget build(BuildContext context) {
    return Container(
      height: (50 * widget.combo.items.length + 125).toDouble(),
      padding: EdgeInsets.only(left: 20),
      decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(40), color: Colors.yellow),
      child: Card(
          elevation: 0,
          color: Colors.transparent,
          child: Column(children: <Widget>[
            ListView.builder(
              shrinkWrap: true,
              itemCount: widget.combo.items.length,
              physics: NeverScrollableScrollPhysics(),
              itemBuilder: (context, index) {
                return Column(
                  children: <Widget>[
                    SizedBox(
                      height: 25,
                    ),
                    OneItem(widget.combo, index, widget.changePrice),

                  ],
                );
              },
            ),
          ])),
    );
  }
}

OneItem 是另一个类,它遍历组合以查找其中的项目数。每个项目与一个复选框一起打印在一行中。用户选择了一些复选框,我需要将这些数据传递给最顶层的类。

class OneItem extends StatefulWidget {
  OneItem(this.combo, this.index, this.changePrice);
  final Combo combo;
  final int index;
  final Function changePrice;
  double priceval;

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

class OneItemState extends State<OneItem> {
  List<bool> Vals = new List();

  @override
  void initState() {
    super.initState();

    int count = widget.combo.items.length;


    Vals = List<bool>.generate(count, (_) => false);
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        Align(
          child: Text(widget.combo.items[widget.index].item),
          alignment: Alignment(-1, 0),
        ),
        Align(
            child: Text(widget.combo.items[widget.index].price),
            alignment: Alignment(0.1, 0)),
        Align(
            child: Checkbox(
              value: Vals[widget.index],
              onChanged: (bool value) {
                setState(() {
                  Vals[widget.index] = value;
                  if(value == true){ widget.priceval = double.parse(widget.combo.items[widget.index].price); }
                  else{double val = double.parse(widget.combo.items[widget.index].price); 
                         widget.priceval = -1*val;}
                  widget.changePrice(widget.priceval);
                  print('${widget.priceval}');
                });
              },
            ),
            alignment: Alignment(0.6, 0)),
      ],
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我会在 Items 类中添加一个变量“复选框”...

    class Items {
      String item;
      String price;
      bool checkbox;
    }
    

    ...并在checkboxes的onChanged回调中修改每一项的checkbox变量。

    Checkbox(
      onChanged: (bool newValue) {
        // set checkbox variable of current item depending on state of UI widget
        ...
      },
    )
    

    您的 MainWidget 可能会保持不变,因为您已经为 ViewCard 提供了 Combo 对象。

    class MyColumnWidget extends StatelessWidget {
      TextEditingController myTextController = TextEditingController();
    
      @override
      Widget build(BuildContext context) {
        return Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
             SizedBox(height: 20,),
             ViewCard(args.combo,_changeprice),
             RaisedButton(
                onPressed: (){
                   // here we have state of checkboxes inside Items objects
                   saveToFirestore(args.combo); 
                },        
             ),
          ]
       )
      }
    }
    

    这是我脑子里写的伪代码。所以它可能无法编译 直接,但它应该让你朝着正确的方向前进。

    另一种方法是使用像 Provider (https://pub.dev/packages/provider) 这样的 StateManagement 库。从长远来看,这可能是更好的方法。

    【讨论】:

    • 用户没有输入任何内容。他们正在选择 CheckBox 并基于此我需要使用该按钮。
    • 所以按钮总是在那里,你需要知道按下按钮时复选框的状态吗?
    • 变量 args.combo 保存从 http 请求接收的数据。此数据与 CheckBox 按钮(也是动态创建的)一起动态显示在 ViewCard 中。现在用户将选择一些复选框,我需要将此信息发送回父类。
    • 告诉我args.combo的数据结构
    • 或更好地在您的问题中提供更多代码,以便人们知道您想要什么
    【解决方案2】:

    我认为这是provider 会做的事情。虽然它不是唯一的选择,但它是 Flutter 团队推荐的状态管理解决方案。

    本质上,问题在于 vals 数组中存储的数据位于 OneItem 小部件内部,该小部件深深嵌套在小部件树中,并且您希望在小部件树的另一部分中使用该信息。解决方案是在将使用数据的分支的根部(在本例中为 ViewCard 上方)实例化数据,然后使用 Provider 小部件将复选框值列表“提供”给 OneItem 小部件和按钮正在使用 Provider.of&lt;data-type-you-are-providing>(context) 提交数据。

    【讨论】:

      猜你喜欢
      • 2018-09-24
      • 2020-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 1970-01-01
      • 2020-08-20
      • 2021-09-26
      • 1970-01-01
      相关资源
      最近更新 更多