I have a logic/conceptual problem that I don't know how to solve.
From API I get an array of objects with dynamic length:
data = [{price: 10, label: 'a'}, {price: 2, label: 'd'}, {price: 5, label: 'b'}]
Each of this data corresponds (in UI) to a quantity selector so something like this:
a: - 0 (price: 10)
d: - 0 (price: 2)
b: - 0 (price: 5)
And then I need to compute the total price.
User can increase and decrease the quantity of each item. For example the app could be in these states:
a: - 1 (price: 10)
d: - 1 (price: 2)
b: - 0 (price: 5)
total: 12
a: - 2 (price: 10)
d: - 1 (price: 2)
b: - 3 (price: 5)
total: 37
a: - 0 (price: 10)
d: - 4 (price: 2)
b: - 0 (price: 5)
total: 8
...
The problem here is that I don't know how to structure the Widget state.
I created this widget:
class QuantityUI extends StatefulWidget {
const QuantityUI({
Key? key,
required this.name,
required this.price,
required this.counter,
required this.add,
required this.remove,
}) : super(key: key);
final String name;
final double price;
final int counter;
final VoidCallback add;
final VoidCallback remove;
@override
_QuantityUI createState() => _QuantityUI();
}
class _QuantityUI extends State<QuantityUI> {
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: const Icon(Icons.remove), onPressed: widget.counter == 0 ? null : widget.remove),
Text(widget.counter.toString()),
IconButton(icon: const Icon(Icons.add), onPressed: widget.add),
Text(widget.name.capitalize()),
Text('${widget.price}€')
],
);
}
}
and I use it in the parent widget this way:
Column(
children: data.map((Datum d) {
return QuantityUI(
name: d.label,
price: d.price,
counter: priceCounter, // <-- this should be a variable in my state
add: () => setState(() => priceCounter ),
remove: () => setState(() => priceCounter--),
);
}).toList(),
)
This should be dynamic. How can I create n
variables in the state, one for each data
item?
CodePudding user response:
You should add counter
for each of your data items and change that counter
on add
and remove
callbacks.
Here is the working solution:
class Test extends StatefulWidget {
const Test({Key? key}) : super(key: key);
@override
State<Test> createState() => _TestState();
}
class _TestState extends State<Test> {
late List data = [
{"price": 10, "label": 'a'},
{"price": 2, "label": 'd'},
{"price": 5, "label": 'b'}
];
@override
void initState() {
super.initState();
data = data.map((e) {
e['counter'] = 0;
return e;
}).toList();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Column(
children: data.map((d) {
return QuantityUI(
name: d["label"] as String,
price: (d["price"] as int).toDouble(),
counter: (d["counter"]) as int,
add: () => setState(() => d["counter"] ),
remove: () => setState(() => d["counter"]--),
);
}).toList(),
)),
);
}
}