In Flutter, how to fix truncated text in PopupMenuItem Widget on larger screen size?

Viewed 848

In the screenshot below, there is a UI crash where the PopupMenuItem text gets truncated for the larger screen size, but is fully visible for the more narrow screen.

What's the best way to resolve this error?

Running the code below, at a minimum I would expect the opposite of what the screen shot shows.

As far as I can tell, I am not specifying any width restrictions.

Code sets unique color backgrounds to indicate space taken by which widget.

enter image description here

import 'package:flutter/material.dart';

main() {
  runApp(Main2DemoApp());
}

class Main2DemoApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Main2DemoScreen(),
    );
  }
}

class Main2DemoScreen extends StatefulWidget {
  @override
  _Main2DemoState createState() => _Main2DemoState();
}

class _Main2DemoState extends State<Main2DemoScreen> {
  static const int EMAIL_CONVERSATION = 11;

  AppScale _scale;

  @override
  Widget build(BuildContext context) {
    _scale = AppScale(context);

    Widget fullHeaderRow = Row(
      children: <Widget>[
        Container(
          color: Colors.purple[200],
          child: getPopupMenuButton(),
        ),
      ],
    );

    fullHeaderRow = Container(
      color: Colors.amber[200],
      child: fullHeaderRow,
    );

    return Scaffold(
      appBar: AppBar(title: Text('PopupMenuButton Demo')),
      body: fullHeaderRow,
    );
  }

  Widget getPopupMenuButton() {
    Widget emailPopUpItem = PopupMenuItem(
      textStyle: TextStyle(
        color: Colors.white,
        fontSize: _scale.popupMenuItem,
      ),
      child: Row(
        children: [
          Padding(
              padding: EdgeInsets.only(right: 10),
              child: Icon(
                Icons.email,
                color: Colors.white,
                size: _scale.popupMenuItem,
              )),
          Text('Send Email Message Now')
        ],
      ),
      value: EMAIL_CONVERSATION,
    );

    List<PopupMenuEntry<dynamic>> menuWidgets = [emailPopUpItem];
    double iconSize = _scale.popupMenuButton;

    PopupMenuButton popupMenuButton = PopupMenuButton(
      padding: EdgeInsets.all(0),
      color: Colors.lightGreen[700],
      offset: Offset(40, 20),
      shape: RoundedRectangleBorder(borderRadius: new BorderRadius.circular(5)),
      icon: Icon(
        Icons.more_vert,
        color: Colors.white,
        size: iconSize,
      ),
      onSelected: (newValue) {
        print('newValue: $newValue');
      },
      itemBuilder: (context) => menuWidgets,
    );

    return popupMenuButton;
  }
}

class AppScale {
  BuildContext _ctxt;

  AppScale(this._ctxt);

  double get popupMenuButton => scaledWidth(.08);
  double get popupMenuItem => scaledHeight(.025);

  double scaledWidth(double widthScale) {
    return MediaQuery.of(_ctxt).size.width * widthScale;
  }

  double scaledHeight(double heightScale) {
    return MediaQuery.of(_ctxt).size.height * heightScale;
  }
}
3 Answers

The max and min width restriction of the popup menu is defined here: popup_menu.dart:554 and it seems that it is not configurable

const double _kMenuMaxWidth = 5.0 * _kMenuWidthStep;
const double _kMenuMinWidth = 2.0 * _kMenuWidthStep;
...
const double _kMenuWidthStep = 56.0;
...
class _PopupMenu<T> extends StatelessWidget {
...
    final Widget child = ConstrainedBox(
      constraints: const BoxConstraints(
        minWidth: _kMenuMinWidth,
        maxWidth: _kMenuMaxWidth,
      )
...

I think icon and text in Row exceed maximum width of PopupMenuButton. You can wrap Text Widget with Expanded Widget. If so, no error happens.

Row(
     children: [
        Padding(
            padding: EdgeInsets.only(right: 10),
            child: Icon(
               Icons.email,
               color: Colors.white,
               size: _scale.popupMenuItem,
             )
        ),
        // Wrap with Expanded Widget
        Expanded(
         child: Text('Send Email Message Now')
        )
         
     ],
),

As the max width and height are fixed for _PopupMenu class you can wrap the widget by either by Flexible or Expanded widget.

Otherwise you can create your own class by extending _PopupMenu and set your own configurations.

enter image description here

Related