1

I'm trying to build a country selection widget with a DropdownButton which can be used anywhere like in a Row with other widgets (e.g. a label). But when the screen width is too small then I get rendering overflow errors. Flutter is not able to use ellipsis or just cut the text.

Following code is best tested in web. Just make the browser smaller to see the problem. I tried all hints from Flutter - DropdownButton overflow but none worked.

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

File main.dart contains instance var flag which should represent a flag image so this one can have a fixed size but the name should be cut with ellipsis if there is not enough space.

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

Dropdown Overflow Problem

Jemolah
  • 1,962
  • 3
  • 24
  • 41

1 Answers1

1

let's try

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


output in browser: enter image description here

Jahidul Islam
  • 11,435
  • 3
  • 17
  • 38
  • Interesting approach. Could you please elaborate why you wrap the DropdownButton into a SingleChildScrollView? Unfortunately the problem is still there. You see it when running in a browser and make the browser small. – Jemolah Jul 26 '21 at 08:28
  • Unfortunately, I found there is no error. SingleChildScrollView is not mandatory, you can omit it, the wrap layout is horizontal and both the children and the runs are aligned to the start. – Jahidul Islam Jul 26 '21 at 08:47
  • Your browser is still too wide. Make it smaller to see the problem. I have added an image showing the error. – Jemolah Jul 26 '21 at 09:03
  • in my mac, it's smallest. i will try it. – Jahidul Islam Jul 26 '21 at 09:05
  • Well. Wrap was already suggested by Raine (see above). Problem with wrap is that it will break longer rows into multiple lines. This is not expected. The country name should just be ellipsized like: "Antigua and Bar...". This is the expected behavior for Text( overflow: TextOverflow.ellipsis) but it does not work here for whatever reason. – Jemolah Jul 26 '21 at 10:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/235301/discussion-between-jemolah-and-jahidul-islam). – Jemolah Jul 26 '21 at 11:02