0

I am write a PreferredSizeWidget implementation. My widget wraps a single Text widget. To properly calculate the required height I need to multiply the text size by the MediaQuery.textScaleFactor.

The only way to know the size of the widget is to have access to the parent MediaQuery. I do not have access to the build context inside the PreferredSizeWidget getSize method.

How can I get around this limitation of PreferredSizeWidget?

Scorb
  • 1,654
  • 13
  • 70
  • 144

2 Answers2

1

You can pass in the textscale factor in the constructor (as mentioned by @Scorb) like this:

class AppHeader extends StatelessWidget implements PreferredSizeWidget {
  final double textScaleFactor;

  const AppHeader({
    super.key,        
    this.textScaleFactor = 1.0,
  });

  @override
  Widget build(BuildContext context) {
    ...
  }

  @override
  Size get preferredSize => Size.fromHeight(
        80 + (textScaleFactor * 40),
      );
}

and use it like so:

Scaffold(
  appBar: AppHeader(
    textScaleFactor: MediaQuery.of(context).textScaleFactor,
  ),
);
Colin
  • 11
  • 1
-1

In short, you can't.

The preferredSize getter needs to return a fixed size. It cannot be some dynamic value determined at runtime because the property is part of the widget, not the element(state), so you won't have access to BuildContext in the getter.

See this answer for some workarounds: https://stackoverflow.com/a/62708948/1032613

If none of those workarounds suit your needs, you can consider dropping Scaffold altogether (if you don't really need a Scaffold anyway). Or, if you use other nice Scaffold things such as the "floating action button", you can consider dropping the appBar property of Scaffold, and design your own custom app bar as part of the Scaffold's body, for example, use a Column() as its body, and put your own app bar there.

WSBT
  • 33,033
  • 18
  • 128
  • 133
  • What about just passing a context as the parameter of the custom PreferredSizeWdigets constructor? – Scorb Apr 24 '22 at 03:40
  • @Scorb terrible idea, read more about what a context is, and you will see why you should never pass it to a widget constructor. – WSBT Apr 24 '22 at 04:54
  • Even if it is a StatelessWidget? Because I have been doing that with zero errors in the past. – Scorb Apr 24 '22 at 17:58