How to change variable of a stateful widget from another widget?

Question

Asked by Edoardo on November 15, 2021 (source).

How to change a variable of a Widget from another widget? This is the main stateful widget called HomePage:

class _HomePageState extends State<HomePage> {
  @override
  num counter = 0;

  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Title")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [Text(counter.toString()), CardWidget()],
          ),
        ));
  }
}

This is CardWidget which is added to HomePage:

class CardWidget extends StatefulWidget {
  const CardWidget({Key? key}) : super(key: key);

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

class _CardWidgetState extends State<CardWidget> {
  @override
  Widget build(BuildContext context) {
    return Card(
        child: Column(
      children: [
        Text("Press the button to increment the counter"),
        ElevatedButton(
          onPressed: () {
            //Something here to increment the counter in HomePage
          },
          child: const Text('Increment'),
        ),
      ],
    ));
  }
}

This is what is shown on the screen: enter image description here

Is it possible to create a connection between the two widgets: if I tap the button something happens in the HomePage Widget? (similar to delegate in UIKit)

Answer

Question answered by Miftakhul A (source).

You can pass Function parameter. In your CardWidget add Function parameter.

class CardWidget extends StatefulWidget {
  //Add clicked function
  final Function onClicked;
  const CardWidget({Key? key, required this.onClicked}) : super(key: key);

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

class _CardWidgetState extends State<CardWidget> {
  int _count = 0;
  @override
  Widget build(BuildContext context) {
    return Card(
        child: Column(
      children: [
        Text("Press the button to increment the counter"),
        ElevatedButton(
          onPressed: () {
            //Something here to increment the counter in HomePage
            //Execute `onClicked` and pass parameter you want
            _count++;
            widget.onClicked(_count);
          },
          child: const Text('Increment'),
        ),
      ],
    ));
  }
}

then on HomePage add onClicked parameter

class _HomePageState extends State<HomePage> {
  @override
  num counter = 0;

  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Fontanelle")),
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.center,
            children: [
               Text(counter.toString()),
               CardWidget(
                //Add onClicked
                 onClicked:(count){
                    print("Clicked "+count.toString());
                 }
               )
            ],
          ),
        ));
  }
}
DART DELEGATES FLUTTER FLUTTER-LAYOUT WIDGET
SHARE: