Mayank PATEl
Mayank PATEl

Reputation: 123

Flutter - Pass state change function to child widget and update state

Home Page

I am new to flutter and building a sample app to learn it. In the above screenshot, I have created multiple widgets. My main widget contains the following widget.

  1. Boy Girl Selector
  2. Common Card
    1. CounterButton (Plus or Minus)
  3. Calculate Button

My main widget has two counter - age & weight. CommonCard has below property : incrementFunction() : I am setting this value from MainWidget as below. decrementFunction()

  ageIncrement() {
    setState(() {
      age++;
    });
  }
  ageDecrement() {
    setState(() {
      age--;
    });
  }

value : age declared in main widget is passed to this value.

CounterButton has below property. onPressed: increment or decrement function from parent widget is passed here through card widget.

If I keep whole code in main widget then it is working properly. But if I create multiple widget and pass increment and decrement function as argument in child widget onPressed on plus and minus is not working propely. Please share your thoughts. I am missing some fundamental of communication between child and parent widget.

Upvotes: 5

Views: 8155

Answers (1)

osaxma
osaxma

Reputation: 2984

There are different ways to achieve what you like as there are a couple of different state management techniques such as Dependency Injection, ChangeNotifier, BLoC, and so on (search for Flutter State Management for more details).

Here's an example of how you can achieve this on the famous counter example. This example is using dependency injection (we are passing the increment function to the a child widget as callback function). You can copy the code and past it on DartPad to quickly test it and see how it works:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

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

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            SizedBox(height: 50),
            MySecondButton(secondButtonIncrement: incrementCounter),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}

class MySecondButton extends StatelessWidget {
  MySecondButton({Key key, this.secondButtonIncrement}) : super(key: key);
  final VoidCallback secondButtonIncrement;

  @override
  Widget build(BuildContext context) {
    return FlatButton(
        child: Text("Second Button"),
        onPressed: () {
          secondButtonIncrement();
        },
        color: Colors.blue);
  }
}

I hope that helps.

Upvotes: 8

Related Questions