Flutter: how to get parent widget variable?

9,495

I want the color to change based on some logic around the count variable, how can I access the count variable from within the TestButton widget? E.g. if count is a multiple of three then the button should be red, otherwise blue.

You need to pass count down to the child and let the child to build itself based on that value.

Don't try to access the parent widget. In declarative programming you can only update states and rebuild trees.

Here's a good video about state management in Flutter: https://www.youtube.com/watch?v=HrBiNHEqSYU

Share:
9,495
Pigna
Author by

Pigna

Updated on December 18, 2022

Comments

  • Pigna
    Pigna over 1 year

    I used the example below to test and learn how to call parent functions from child widget. When you click the TestButton, the countRefresh function is called and the variable count increases by 1. Right now the button changes color each time it is clicked (either blue or red).

    QUESTION: say that I want the color to change based on some logic around the count variable, how can I access the count variable from within the TestButton widget? E.g. if count is a multiple of three then the button should be red, otherwise blue.

    I read about InheritedWidgets, but it seems like variables must be final inside InheritedWidgets (if I don't put final before int count = 0; I get the 'this class is marked as immutable' message error). But based on this example I need count to change each time the button is clicked. What's the alternative to InheritedWidgets?

    import 'package:flutter/material.dart';
    
    class Test extends StatefulWidget {
      static const String id = 'test';
      @override
      _TestState createState() => _TestState();
    }
    
    class _TestState extends State<Test> {
      int count = 0;
      Color color = Colors.red;
    
      void refreshCount() {
        setState(() {
          count += 1;
        });
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child:
                Text('The button was pressed $count time${count == 1 ? '' : 's'}'),
          ),
          floatingActionButton: TestButton(
            color: color,
            notifyParent: refreshCount,
          ),
        );
      }
    }
    
    class TestButton extends StatefulWidget {
      TestButton({
        @required this.color,
        @required this.notifyParent,
      });
      final Color color;
      final void Function() notifyParent;
      @override
      _TestButtonState createState() => _TestButtonState();
    }
    
    class _TestButtonState extends State<TestButton> {
      Color color;
      void initState() {
        color = widget.color;
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return GestureDetector(
          onTap: () {
            widget.notifyParent();
            setState(() {
              color = color == Colors.red ? Colors.blue : Colors.red;
            });
          },
          child: Container(
            child: Icon(
              Icons.add,
              size: 80,
            ),
            color: color,
          ),
        );
      }
    }
    
  • Pigna
    Pigna over 4 years
    Yes, I thought about that! But what if I had multiple children that need to access the variable? Should I pass it to all of them? Worst case scenario: say that I have hundreds/thousands of children widgets that need that parenti variable. Isn't it kind of wasteful?
  • Andrey Gordeev
    Andrey Gordeev over 4 years
    Then use Provider. See the video I mentioned.