Search code examples
fluttertextlayoutrowellipsis

Using space left by siblings in a row - MediaQuery.of(): context is null


I'm trying to arrange two texts in a row. The second text is only a few words, but the first can be very long. My goal is to show the second text fully, and fill the remaining space with the first. If the first widget is too wide, I want to truncate it with an ellipsis.

Expected layout: expected layout

My code is

class MyHomePage extends StatelessWidget {
  
  @override
  Widget build(BuildContext context) {
    GlobalKey key = GlobalKey();
    return Row(
      children: [
        Container(
            child: Text("Really really really long long long teeeeext",
                maxLines: 1,
                overflow: TextOverflow.ellipsis),
                width: MediaQuery.of(context).size.width - MediaQuery.of(key.currentContext).size.width),
        Text("short text", key: key)
      ],
    );

  }
}

It fails with The following assertion was thrown building MyHomePage(dirty, dependencies: [MediaQuery]): I/flutter (28083): 'package:flutter/src/widgets/media_query.dart': Failed assertion: line 810 pos 12: 'context != I/flutter (28083): null': is not true. I guess because the Flutter engine hasn't started rendering the "short text" widget yet, so it's size is unknown at this time.

Any help will be appreciated.


Solution

  • MediaQuery.of(context).size isn't available during build phase. While building the widget, sizes aren't calculated yet.

    However you don't need MediaQuery.of(context).size to implement the layout. Instead, you can simply wrap left text with Expanded. Then it will take all remaining space (total width minus right text width).

    Row(
      children: [
        Expanded(
          child: Text(
            "Really really really long long long teeeeext 123 123 123 123 123 123 123 123",
            maxLines: 1,
            overflow: TextOverflow.ellipsis,
          ),
        ),
        Text(
          "short text",
        ),
      ],
    )
    

    Result:

    screenshot