Lalit
Lalit

Reputation: 23

How to pass set state value changes from parent to child widget in flutter?

I've declared an int 'k' and I'm changing it's value from user's input using set state function. The value changes of 'k' are reflected on Nutrition function. But when passing value of 'k' to checkbbox function it is always 2(initial value).

Basically set state changes are not passed to checkbox even though the Nutrition widget is rebuilding.

    class Nutrition extends StatefulWidget {
      @override
      _Nutrition createState() => _Nutrition();
    }
    
    class _Nutrition extends State<Nutrition> {
      DateTime now = DateTime.now().toLocal();
      int k = 2;

@override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('CqMyOE via Nutrition'),
      ),
      body: SingleChildScrollView(
        child: Container(
          color: Colors.grey[200],
          child: Column(
            mainAxisAlignment: MainAxisAlignment.start,
            children: [
              Row(
                mainAxisAlignment: MainAxisAlignment.spaceAround,
                children: [
                  FlatButton(
                    onPressed: () {
                      setState(() {
                        k = 0;
                      });
                    },
                    child: Text(
                      DateFormat('dd-MMM').format(now),
                    ),
                    color: (k == 0) ? Colors.greenAccent : Colors.grey,
                  ),
                  FlatButton(
                    onPressed: () {
                      setState(() {
                        k = 1;
                      });
                    },
                    child: Text(
                      DateFormat('dd-MMM')
                          .format(now.subtract(new Duration(days: 1))),
                    ),
                    color: (k == 1) ? Colors.greenAccent : Colors.grey,
                  ),
                  FlatButton(
                    onPressed: () {
                      setState(() {
                        k = 2;
                      });
                    },
                    child: Text(
                      DateFormat('dd-MMM')
                          .format(now.subtract(new Duration(days: 2))),
                    ),
                    color: (k == 2) ? Colors.greenAccent : Colors.grey,
                  ),
                  FlatButton(
                    onPressed: () {
                      setState(() {
                        k = 3;
                      });
                    },
                    child: Text(
                      DateFormat('dd-MMM')
                          .format(now.subtract(new Duration(days: 3))),
                    ),
                    color: (k == 3) ? Colors.greenAccent : Colors.grey,
                  ),
                ],
              ),
              Card(
                child: Row(
                  children: [
                    Expanded(
                      flex: 1,
                      child: Padding(
                        padding: const EdgeInsets.fromLTRB(8, 16, 8, 16),
                        child: Text('Salt awareness' + k.toString()),
                      ),
                    ),
                    Expanded(
                      child: Row(
                        children: [
                          CheckBox(
                            10,
                            nutritionDB.get(curDate).record[10] ?? '0',
                            k,
                          ),
                        ],
                      ),
                    ),
                  ],
                ),
              ),
             ]
           )
         )
       )
     )
}

class CheckBox extends StatefulWidget {
  final int index;
  final String value;
  // final String date;
  final int k;
  CheckBox(this.index, this.value, this.k);
  @override
  State<StatefulWidget> createState() =>
      _CheckBox(index, value == '1' ? true : false, k);
}

class _CheckBox extends State<CheckBox> {
  int index;
  bool checked;
  // String date;
  int k;
  _CheckBox(this.index, this.checked, this.k);

  @override
  Widget build(BuildContext context) {
    return IconButton(
      icon: Icon(
        checked ? Icons.check : Icons.clear,
      ),
      color: checked ? Colors.green : Colors.red,
      onPressed: () {
        final nutritionDB = Hive.box<NutritionData>('NutritionDB');

        List<String> temp = nutritionDB.get(day3).record;
        temp[index] = !checked ? '1' : '0';
        NutritionData temp1 = new NutritionData(temp);
        nutritionDB.put(day3, temp1);
        setState(() {
          print(k);
          checked = !checked;
        });
      },
    );
  }
}

Upvotes: 2

Views: 1094

Answers (1)

chunhunghan
chunhunghan

Reputation: 54365

You can copy paste run full code below
For demo purpose, I add k value before IconButton
You can in didUpdateWidget reset k = widget.k;
code snippet

class _CheckBox extends State<CheckBox> {
  ...

  @override
  void didUpdateWidget(covariant CheckBox oldWidget) {
    if (oldWidget.k != widget.k) {
      k = widget.k;
    }

    super.didUpdateWidget(oldWidget);
  }

working demo

enter image description here

full code

import 'package:flutter/material.dart';
import 'package:intl/intl.dart';

class Nutrition extends StatefulWidget {
  @override
  _Nutrition createState() => _Nutrition();
}

class _Nutrition extends State<Nutrition> {
  DateTime now = DateTime.now().toLocal();
  int k = 2;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text('CqMyOE via Nutrition'),
        ),
        body: SingleChildScrollView(
            child: Container(
                color: Colors.grey[200],
                child: Column(
                    mainAxisAlignment: MainAxisAlignment.start,
                    children: [
                      Row(
                        mainAxisAlignment: MainAxisAlignment.spaceAround,
                        children: [
                          FlatButton(
                            onPressed: () {
                              setState(() {
                                k = 0;
                              });
                            },
                            child: Text(
                              DateFormat('dd-MMM').format(now),
                            ),
                            color: (k == 0) ? Colors.greenAccent : Colors.grey,
                          ),
                          FlatButton(
                            onPressed: () {
                              setState(() {
                                k = 1;
                              });
                            },
                            child: Text(
                              DateFormat('dd-MMM')
                                  .format(now.subtract(new Duration(days: 1))),
                            ),
                            color: (k == 1) ? Colors.greenAccent : Colors.grey,
                          ),
                          FlatButton(
                            onPressed: () {
                              setState(() {
                                k = 2;
                              });
                            },
                            child: Text(
                              DateFormat('dd-MMM')
                                  .format(now.subtract(new Duration(days: 2))),
                            ),
                            color: (k == 2) ? Colors.greenAccent : Colors.grey,
                          ),
                          FlatButton(
                            onPressed: () {
                              setState(() {
                                k = 3;
                              });
                            },
                            child: Text(
                              DateFormat('dd-MMM')
                                  .format(now.subtract(new Duration(days: 3))),
                            ),
                            color: (k == 3) ? Colors.greenAccent : Colors.grey,
                          ),
                        ],
                      ),
                      Card(
                        child: Row(
                          children: [
                            Expanded(
                              flex: 1,
                              child: Padding(
                                padding:
                                    const EdgeInsets.fromLTRB(8, 16, 8, 16),
                                child: Text('Salt awareness' + k.toString()),
                              ),
                            ),
                            Expanded(
                              child: Row(
                                children: [
                                  CheckBox(
                                    10,
                                    "nutritionDB.get(curDate).record[10]" ??
                                        '0',
                                    k,
                                  ),
                                ],
                              ),
                            ),
                          ],
                        ),
                      ),
                    ]))));
  }
}

class CheckBox extends StatefulWidget {
  final int index;
  final String value;
  // final String date;
  final int k;
  CheckBox(this.index, this.value, this.k);
  @override
  State<StatefulWidget> createState() =>
      _CheckBox(index, value == '1' ? true : false, k);
}

class _CheckBox extends State<CheckBox> {
  int index;
  bool checked;
  // String date;
  int k;
  _CheckBox(this.index, this.checked, this.k);

  @override
  void didUpdateWidget(covariant CheckBox oldWidget) {
    if (oldWidget.k != widget.k) {
      k = widget.k;
    }

    super.didUpdateWidget(oldWidget);
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      children: [
        Text("k $k"),
        IconButton(
          icon: Icon(
            checked ? Icons.check : Icons.clear,
          ),
          color: checked ? Colors.green : Colors.red,
          onPressed: () {
            //final nutritionDB = Hive.box<NutritionData>('NutritionDB');

            //List<String> temp = nutritionDB.get(day3).record;
            //temp[index] = !checked ? '1' : '0';
            //NutritionData temp1 = new NutritionData(temp);
            //nutritionDB.put(day3, temp1);
            setState(() {
              print(k);
              checked = !checked;
            });
          },
        ),
      ],
    );
  }
}

void main() {
  runApp(MyApp());
}

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

Upvotes: 3

Related Questions