Skip to content

LayoutBuilder's descendant widgets should not rebuild more than once in the same frame #146379

@LongCatIsLooong

Description

@LongCatIsLooong
  testWidgets('LayoutBuilder rebuids twice', (WidgetTester tester) async {
    int built = 0;
    final target = LayoutBuilder(
      builder: (context, constraints) {
        return Builder(builder: (context) {
          built += 1;
          MediaQuery.of(context);
          return const Placeholder();
        });
      },
    );
    expect(built, 0);

    await tester.pumpWidget(MediaQuery(
      data: const MediaQueryData(size: Size(400.0, 300.0)),
      child: Center(
        child: SizedBox(
          width: 400.0,
          child: target,
        ),
      ),
    ));
    expect(built, 1);

    await tester.pumpWidget(MediaQuery(
      data: const MediaQueryData(size: Size(300.0, 400.0)),
      child: Center(
        child: SizedBox(
          width: 300.0,
          child: target,
        ),
      ),
    ));
    expect(built, 2);
  });

The following TestFailure was thrown running a test:
Expected: <2>
Actual: <3>

This came up again in #143249: we can't use a LayoutBuilder to get the incoming constraints because a google internal test failure caused by this.

This becomes problematic when a disposable object (such as a controller) is passed down the widget tree as a widget parameter, across the LayoutBuilder boundary:

ControllerOwner -> LayoutBuilder -> IntermediateWidget -> ControllerUser.

If ControllerUser rebulids without IntermediateWidget rebuilding (as seen in the test), it may keep using an outdated / disposed controller.

Metadata

Metadata

Labels

P2Important issues not at the top of the work lista: tests"flutter test", flutter_test, or one of our testsfound in release: 3.19Found to occur in 3.19found in release: 3.22Found to occur in 3.22frameworkflutter/packages/flutter repository. See also f: labels.has reproducible stepsThe issue has been confirmed reproducible and is ready to work onr: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions