2
votes

I have two stateful widgets: ParentWidget and ChildWidget.

The ChildWidget has a gesture detector wrapping a container and text. When I call onTap the state of the Parent (status increased by 1) is updated properly but setState() is not refreshing the UI.

I tried everything: global keys, inherited widget but nothing works.

Interestingly if I change the ChildWidget to a stateless one then everything start working. Any ideas would be super helpful. pk

Here is the code:

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

class ParentWidget extends StatefulWidget {
  @override
  _ParentWidgetState createState() => _ParentWidgetState();
}

class _ParentWidgetState extends State<ParentWidget> {
  int status = 1;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.white,
      appBar: AppBar(
        backgroundColor: Hexcolor('#1c486d'),
        title: Text(
          'Test',
        ),
      ),
      body: ChildWidget(
        child: GestureDetector(
          onTap: () {
            status = status + 1;
            setState(() {}); // this is the problematic piece of code.
          },
          child: Container(
            color: Colors.blue,
            width: 100,
            height: 100,
            child: Text('PARENT:' + status.toString()),
          ),
        ),
      ),
    );
  }
}

class ChildWidget extends StatefulWidget {
  final Widget child;
  ChildWidget({this.child});
  @override
  _ChildWidgetState createState() => _ChildWidgetState(child);
}

class _ChildWidgetState extends State<ChildWidget> {
  Widget child;

  _ChildWidgetState(this.child);

  @override
  Widget build(BuildContext context) {
    return child;
  }
}

2
If my answe is useful, please accept it. Thanks. Otherwise let me know.lenz
Hi Genchi, thanks for the comment. I know that in this example it is useless, however this is only a 'strawman' of a more complex I am working on where the child needs to be stateful.PK Przemek

2 Answers

0
votes

You can pass the parent's status to the ChildWidget so that when the parent's status changes, the ChildWidget's state changes and its build method be called.

body: GestureDetector(
        onTap: () {
          setState(() {
            status = status + 1;
          });
        },
        child: ChildWidget(status: status),
      ),
    );
  }
}

class ChildWidget extends StatefulWidget {
  final int status;

  ChildWidget({this.status});
  @override
  _ChildWidgetState createState() => _ChildWidgetState();
}

class _ChildWidgetState extends State<ChildWidget> {
  _ChildWidgetState();

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blue,
      width: 100,
      height: 100,
      child: Text('PARENT:' + widget.status.toString()),
    );
  }
}
0
votes

Try not making the child final

  class ChildWidget extends StatefulWidget {
  Widget child;
  ChildWidget({this.child});

  @override
  _ChildWidgetState createState() => _ChildWidgetState(child);
  }