Во Flutter, как исправить усеченный текст в виджете PopupMenuItem при большем размере экрана?

#flutter #dart

#флаттер #дротик

Вопрос:

На скриншоте ниже происходит сбой пользовательского интерфейса, при котором текст PopupMenuItem усекается для большего размера экрана, но полностью виден для более узкого экрана.

Каков наилучший способ устранить эту ошибку?

Выполняя приведенный ниже код, как минимум, я ожидал бы противоположного тому, что показывает снимок экрана.

Насколько я могу судить, я не указываю никаких ограничений по ширине.

Код устанавливает уникальные цветные фоны, чтобы указать место, занимаемое каким виджетом.

введите описание изображения здесь

 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;
  }
}
  

Комментарии:

1. Вы не проверяете ориентацию устройства. например, если устройство находится в альбомной ориентации, то ширина больше высоты и наоборот.

Ответ №1:

Ограничение максимальной и минимальной ширины всплывающего меню определено здесь: popup_menu.dart:554 и, похоже, оно не настраивается

 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,
      )
...
  

Ответ №2:

Я думаю, что значок и текст в строке превышают максимальную ширину PopupMenuButton. Вы можете обернуть текстовый виджет расширенным виджетом. Если это так, ошибки не произойдет.

 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')
        )
         
     ],
),
  

Ответ №3:

Поскольку максимальная ширина и высота фиксированы для _PopupMenu класса, вы можете обернуть виджет либо с помощью Flexible , либо Expanded с помощью виджета.

В противном случае вы можете создать свой собственный класс, расширив _PopupMenu и установив свои собственные конфигурации.

введите описание изображения здесь