我有一个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中使用它们。
编辑:args.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是另一个类,它通过组合进行迭代以查找其中的项目数。每个项目与CheckBox一起打印在一行中。用户选中了一些复选框,这就是我需要传递给最高级课程的数据。
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)),
],
);
}
}
答案 0 :(得分:1)
我将在Items类中添加一个变量“复选框” ...
class Items {
String item;
String price;
bool checkbox;
}
...,然后在复选框的onChanged回调中修改每个项目的复选框变量。
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);
},
),
]
)
}
}
这是我脑海中写的伪代码。因此它可能无法编译 直接进行操作,但这应该可以指引您正确的方向。
另一种方法是使用诸如提供程序(https://pub.dev/packages/provider)之类的StateManagement库。从长远来看,这可能是更好的方法。
答案 1 :(得分:0)
我认为provider会很好。尽管这不是唯一的选择,但它是Flutter团队推荐的状态管理解决方案。
从本质上讲,问题在于存储在vals数组中的数据位于OneItem小部件内部,该部件深深嵌套在小部件树中,并且您想在小部件树的另一部分中使用该信息。解决方案是在将要使用数据的分支的根处(在本例中为ViewCard上方)实例化数据,然后使用提供程序小部件将复选框值列表“提供”给OneItem小部件和按钮。正在使用Provider.of <data-type-you-are-providing
>(上下文)提交数据。