Learning Flutter and I am building a counter that I would like to use for a cart. I have a problem retrieving the integer value of the counter stateful widget I created and i'd like a Text to update itself with the value of the Counter.
Here is the Code for the Counter
import 'package:flutter/material.dart';
class TheCounter extends StatefulWidget {
int counter = 0;
int get counterValue => counter;
@override
_TheCounterState createState() => _TheCounterState();
}
class _TheCounterState extends State<TheCounter> {
void increaseCounter() {
setState(() {
if (widget.counter >= 0) {
widget.counter++;
}
});
}
void decreaseCounter() {
setState(() {
if (widget.counter > 0) {
widget.counter--;
}
});
}
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.add), onPressed: increaseCounter),
Text('${widget.counter}'),
IconButton(icon: Icon(Icons.remove), onPressed: decreaseCounter)
],
);
}
}
And here is the main.dart file
import 'package:counter/counter.dart';
import 'package:flutter/material.dart';
void main() {
runApp(Count());
}
class Count extends StatelessWidget {
@override
Widget build(BuildContext context) {
int counting = TheCounter().counterValue;
return MaterialApp(
title: 'Counter',
home: Scaffold(
appBar: AppBar(
title: Text('Counter Test'),
),
body: Column(
children: [
TheCounter(),
Text('$counting'),
TheCounter(),
TheCounter(),
],
),
),
);
}
}
I'd like the Text to update itself with the value of the counter whenever the add or remove button is clicked. What do I do to achieve that?
Firstly, we need to make a decision where the update will happen. In this case the Count
widget text need to update.
Therefore, need to convert this as StatefulWidget
.
Next thing is how we can retrieve counter from TheCounter
widget. You can use callback method, or state management package like provider, riverpod, bloc etc. You can check the doc
Here I am using a function that will get update value on Count
whenever the count value change on TheCounter
widget.
void main() {
runApp(MaterialApp(title: 'Counter', home: Count()));
}
class Count extends StatefulWidget {
const Count({Key? key}) : super(key: key);
@override
State<Count> createState() => _CountState();
}
class _CountState extends State<Count> {
int initNumberOfCounter = 4;
late List<int> countersValue = List.generate(initNumberOfCounter, (index) => 0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Counter Test'),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
countersValue.add(0);
});
},
),
body: Column(
children: [
Expanded(
child: ListView.builder(
itemCount: countersValue.length,
itemBuilder: (context, index) {
return Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
TheCounter(
initCountValue: countersValue[index],
countValueCallback: (v) {
setState(() {
countersValue[index] = v;
});
},
),
const SizedBox(
width: 40,
),
Text("${countersValue[index]}"),
],
);
},
),
)
],
),
);
}
}
class TheCounter extends StatefulWidget {
final Function(int) countValueCallback;
final int initCountValue;
const TheCounter({
Key? key,
required this.countValueCallback,
this.initCountValue = 0,
}) : super(key: key);
@override
_TheCounterState createState() => _TheCounterState();
}
class _TheCounterState extends State<TheCounter> {
///this use within the current state
late int counter;
@override
void initState() {
super.initState();
///set counter value for the 1st time
counter = widget.initCountValue;
}
void increaseCounter() {
setState(() {
if (counter >= 0) {
counter++;
}
});
/// back to parent widget
widget.countValueCallback(counter);
}
void decreaseCounter() {
setState(() {
if (counter > 0) {
counter--;
}
});
widget.countValueCallback(counter);
}
@override
Widget build(BuildContext context) {
return Row(
children: [
IconButton(icon: Icon(Icons.add), onPressed: increaseCounter),
Text('${counter}'),
IconButton(icon: Icon(Icons.remove), onPressed: decreaseCounter)
],
);
}
}