skip to Main Content

Because of some requirements, I need to support big text size on my app. And because of that I’m having a bit of issue with a DropdownButtonFormField that contains long text. I was able to fix the right overflow with isExpanded: true, but now the issue is, I think, DropdownButtonFormField doesn’t really know how to handle isExpanded: true properly. Here’s what my DropdownButtonFormField currently looks like:

enter image description here

Here’s what my code looks like:

ConstrainedBox(
    constraints: BoxConstraints(
       minHeight: 70.0,
     ),,
    child: DecoratedBox(
      decoration: CustomViewStyle.textBoxDecoration,
      child: Padding(
        padding: const EdgeInsets.all(8.0),
        child: DropdownButtonFormField<PermitCertificateType>(
            isExpanded: true,
            style: CustomTextStyle.textBoxTextStyle,
            value: widget.permitCertificateRecord?.permitCertificateType,
            decoration: InputDecoration(
                hintText: 'Permit/Certificate Type',
                hintStyle: CustomTextStyle.dropdownHintTextStyle,
                errorStyle: CustomTextStyle.errorStyle
            ),
            hint: Text("Permit/Certificate Type",
              style: CustomTextStyle.adapterTextTextStyle,),
            items: snapshot.data!.map((PermitCertificateType value) {
              return DropdownMenuItem<PermitCertificateType>(
                value: value,
                child: Wrap(
                    children: [
                      Text(value.name,
                        style: CustomTextStyle.textBoxTextStyle,),
                    ]
                ),
              );
            }).toList(),
            validator: (value) {
              if (value == null) {
                return 'Missing Permit/Certificate Type';
              }
              return null;
            },
            onChanged: (text) async {
              
            },
            onSaved: (value) {
              _permitCertificateTypeId = value!.id;
            },
          ),
      ),
    ),
  ),

itemHeight doesn’t help because it only affects the item of the dropdown itself, not the displayed one after choosing an item or when setting an initial value.

2

Answers


  1. Chosen as BEST ANSWER

    I think I found the easiest solution for this, albeit, may not look that good for single line items. Set the DropdownButtonFormField or similar's isDense to false. You don't even need a Wrap before the DropdownMenuItem's Text.

    Here's what my current code looks like:

    DropdownButtonFormField<PermitCertificateType>(
        isExpanded: true,
        isDense: false, // <- this is the fix
        style: CustomTextStyle.textBoxTextStyle,
        value: widget.permitCertificateRecord?.permitCertificateType,
        decoration: InputDecoration(
            hintText: 'Permit/Certificate Type',
            hintStyle: CustomTextStyle.dropdownHintTextStyle,
            errorStyle: CustomTextStyle.errorStyle
        ),
        hint: Text("Permit/Certificate Type",
          style: CustomTextStyle.adapterTextTextStyle,),
        items: snapshot.data!.map((PermitCertificateType value) {
          return DropdownMenuItem<PermitCertificateType>(
            value: value,
            child: Text(value.name,
              style: CustomTextStyle.textBoxTextStyle,)
          );
        }).toList(),
        validator: (value) {
          if (value == null) {
            return 'Missing Permit/Certificate Type';
          }
          return null;
        },
        onChanged: (text) async {
          
        },
        onSaved: (value) {
          
        },
      ),
    

  2. I highly recommend using this code. Here, I manage the short and long text by initially checking whether the text is overflowing or not. If the option is short and not overflowing, it will display as it is; otherwise, it will display as rotating text (AKA Marquee text).

    For the rotating text (AKA Marquee text), consider using this package: https://pub.dev/packages/text_marquee

    import "package:flutter/material.dart";
    import "package:marquee/marquee.dart";
    
    void main() {
      WidgetsFlutterBinding.ensureInitialized();
    
      runApp(const MainApp());
    }
    
    class MainApp extends StatelessWidget {
      const MainApp({super.key});
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: HomeScreen(),
        );
      }
    }
    
    class HomeScreen extends StatefulWidget {
      const HomeScreen({super.key});
    
      @override
      State<HomeScreen> createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
      final List<String> options = <String>[
        "Short Answer 1",
        "Short Answer 2",
        "Very Very Very Very Very Very Very Very Very Very Long Answer 3",
        "Very Very Very Very Very Very Very Very Very Very Long Answer 4",
      ];
    
      String? selectedValue;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(),
          body: SafeArea(
            child: Column(
              children: <Widget>[
                DropdownButtonFormField<String?>(
                  isExpanded: true,
                  value: selectedValue,
                  items: options.map(
                    (String value) {
                      return DropdownMenuItem<String?>(
                        value: value,
                        child: LayoutBuilder(
                          builder: (
                            BuildContext context,
                            BoxConstraints constraints,
                          ) {
                            return SizedBox(
                              height: kToolbarHeight / 2,
                              width: constraints.maxWidth,
                              child: Align(
                                alignment: Alignment.centerLeft,
                                child: _overflowing(
                                  text: value,
                                  maxWidth: constraints.maxWidth,
                                )
                                    ? Marquee(
                                        text: value,
                                        blankSpace: constraints.maxWidth / 3,
                                        pauseAfterRound: const Duration(seconds: 3),
                                      )
                                    : Text(value),
                              ),
                            );
                          },
                        ),
                      );
                    },
                  ).toList(),
                  onChanged: (String? value) {
                    selectedValue = value;
                    setState(() {});
                  },
                ),
              ],
            ),
          ),
        );
      }
    
      bool _overflowing({required String text, required double maxWidth}) {
        final TextPainter textPainter = TextPainter(
          text: TextSpan(text: text),
          maxLines: 1,
          textDirection: TextDirection.ltr,
        )..layout(maxWidth: maxWidth);
        final bool didExceedMaxLines = textPainter.didExceedMaxLines;
        return didExceedMaxLines;
      }
    }
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search