【问题标题】:Flutter - Text overflow in DropdownMenuItemFlutter - DropdownMenuItem 中的文本溢出
【发布时间】:2021-10-02 04:17:37
【问题描述】:

我正在尝试使用 DropdownButton 构建一个国家选择小部件,该小部件可以在任何地方使用,例如在带有其他小部件(例如标签)的行中。但是当屏幕宽度太小时,我会得到渲染溢出错误。 Flutter 无法使用省略号或仅剪切文本。

以下代码最好在 web.xml 中进行测试。只需将浏览器缩小即可查看问题。我尝试了来自Flutter - DropdownButton overflow 的所有提示,但都没有奏效。

flutter --version
Flutter 2.2.3 • channel stable • https://github.com/flutter/flutter.git
Framework • revision f4abaa0735 (4 weeks ago) • 2021-07-01 12:46:11 -0700
Engine • revision 241c87ad80
Tools • Dart 2.13.4

文件 main.dart 包含实例 var flag,它应该代表一个标志图像,因此这个图像可以具有固定大小,但如果有,则名称应该用省略号剪切空间不够。

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Country> countries = [
    Country('FR', 'France'),
    Country('GB', 'Great Britain'),
    Country('AG', 'Antigua and Barbuda Islands')
  ];
  String? flag = null;

  Widget _buildDropdown() {
    return DropdownButton<String>(
//      isExpanded: true,
      items: [
        for (Country country in countries)
          DropdownMenuItem(
            value: country.flag,
            child: Row(
              mainAxisAlignment: MainAxisAlignment.start,
              children: [
                SizedBox(
                  width: 30,
                  child: Text(country.flag),
                ),
//                Expanded( child:
//                Flexible( child:
                Text(
                  country.name,
                  overflow: TextOverflow.ellipsis,
                ),
//                ),
              ],
            ),
          ),
      ],
      onChanged: (String? selectedFlag) => setState(() => flag = selectedFlag!),
      value: flag,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text overflow in Dropdown'),
      ),
      body: Container(
        width: 200,
        child: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _buildDropdown(),
              Text('Selected $flag'),
            ],
          ),),),);}}

class Country {
  String flag;
  String name;
  Country(this.flag, this.name);
}

【问题讨论】:

  • 使用Wrap 小部件代替Row 怎么样?但是会发生的是旗帜在上面,文字在下面。我不认为那是你想要的。
  • 并非如此。国旗应该在国家名称的左边。

标签: flutter rendering overflow dropdownbox


【解决方案1】:

我们试试

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key}) : super(key: key);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List<Country> countries = [
    Country('FR', 'France'),
    Country('GB', 'Great Britain'),
    Country('AG', 'Antigua and Barbuda Islands Antigua and Barbuda IslandsAntigua and Barbuda Islands Antigua and Barbuda IslandsAntigua and Barbuda Islands, Antigua and Barbuda Islands')
  ];

  String flag = null;

  Widget _buildDropdown() {
    return DropdownButton<String>(
      isExpanded: true,
      items: [
        for (Country country in countries)
          DropdownMenuItem(
            value: country.flag,
            child: Wrap(
              children: [
                SizedBox(
                  width: 30,
                  child: Text(country.flag),
                ),
                Container(
                  constraints: new BoxConstraints(
                    minHeight: 20.0,
                    maxHeight: 20.0,
                  ),
                  child: Text(
                    country.name,
                  ),
                ),
              ],
            ),
          ),
      ],
      onChanged: (String selectedFlag) => setState(() => flag = selectedFlag),
      value: flag,
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Text overflow in Dropdown'),
      ),
      body: SingleChildScrollView(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            _buildDropdown(),
            Text('Selected $flag'),
          ],
        ),
      ),
    );
  }
}

class Country {
  String flag;
  String name;

  Country(this.flag, this.name);
}


在浏览器中的输出:

【讨论】:

  • 有趣的方法。您能否详细说明为什么将 DropdownButton 包装到 SingleChildScrollView 中?不幸的是,问题仍然存在。您在浏览器中运行时会看到它并使浏览器变小。
  • 不幸的是,我发现没有错误。 SingleChildScrollView 不是强制的,可以省略,wrap layout 是水平的,children 和 runs 都与 start 对齐。
  • 您的浏览器仍然太宽。将其缩小以查看问题。我添加了一张显示错误的图片。
  • 在我的 Mac 中,它是最小的。我会试试的。
  • 好吧。 Raine 已经建议使用 Wrap(见上文)。 wrap 的问题在于它将较长的行分成多行。这不是预期的。国家名称应该只是省略号,例如:“Antigua and Bar...”。这是 Text(overflow: TextOverflow.ellipsis) 的预期行为,但无论出于何种原因,它在这里都不起作用。
猜你喜欢
  • 2021-01-28
  • 2021-11-05
  • 1970-01-01
  • 2021-09-27
  • 2019-01-04
  • 2023-02-15
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
相关资源
最近更新 更多