1

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?

thearach
  • 27
  • 4

1 Answers1

0

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)
      ],
    );
  }
}

Md. Yeasin Sheikh
  • 54,221
  • 7
  • 29
  • 56
  • I have tried using ChangeNotifier but the issue i had with that was a duplication problem. The instances of the Counter were updating collectively whenever i clicked on just one of them. I seem to be having the same issue with code above, the difference is that the instances of the counter update individually like they should but the Texts are not in sync with Counters so i have to create multiple instances on int counting for it to work properly. – thearach May 14 '22 at 04:30
  • We are using single `counting` variable on two `TheCounter ` that's why you any Of it will change text widget. do you like to have different text? Can you include an image that are you trying to solve? – Md. Yeasin Sheikh May 14 '22 at 04:52
  • Yes, I had to create another int counting for it to work on separate counters, which means I'll have to create a different one for as many counter instances, which is not ideal. Is there another way to solve this? @Yeasin Sheikh – thearach May 14 '22 at 05:10
  • You can use List to solve this – Md. Yeasin Sheikh May 14 '22 at 05:38
  • How exactly can i use List to solve this? @YeasinSheikh – thearach May 16 '22 at 00:28
  • Did you check update answer's snippet? – Md. Yeasin Sheikh May 16 '22 at 03:37
  • Thank you. This works. I am having issues getting it to work within the list.builder for the store though. Thoughts? @YeasinSheikh – thearach May 17 '22 at 23:52
  • Sorry, I am not getting it. Can you include the reference link of the issue, You can also another question by showing your efforts. – Md. Yeasin Sheikh May 18 '22 at 02:43