移除DropdownButton中文本和尾随图标之间的空白间距

7

我有一个下拉菜单,显示一系列字符串。这些字符串的值包含只由四个字母组成的单词和由许多字母组成的单词。当所选项目是只含有四个字母的项目时,这会导致布局问题。可以看到文本和下拉按钮的标记之间存在空白或空间。如何消除这种空白空间?如何根据所选的值调整下拉按钮的大小?

空白空间照片:

进入图像描述

列表:

List<String> textList = ["test", "this_is_a_long_text"];

下拉菜单:

DropdownButtonHideUnderline(
      child: ButtonTheme(
       alignedDropdown: true,
       child: DropdownButton<String>(
        items: textList.map((String dropDownStringItem) {
           return DropdownMenuItem<String>(
                      value: dropDownStringItem,
                      child: Text(dropDownStringItem),
                    );
                  }).toList(),
              onChanged: (String newValueSelected) {
                _onDropDownItemSelected(newValueSelected);
              },
              value: _currentItemSelected,
            ),
          )),

你想让下拉按钮根据所选值调整大小吗? - F Perroch
@FPerroch 是的。我希望它根据所选的值调整大小。 - CoderUni
6个回答

17

作为一种选择,您可以基于PopupMenuButton而不是常规的DropdownButton构建它。

以下是一个示例:

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(child: AwesomeDropdown()),
      ),
    );
  }
}

class AwesomeDropdown extends StatefulWidget {
  @override
  _AwesomeDropdownState createState() => _AwesomeDropdownState();
}

class _AwesomeDropdownState extends State<AwesomeDropdown> {
  final List<String> textList = ["test", "this_is_a111111_long_text"];
  String _currentItemSelected;

  @override
  void initState() {
    super.initState();
    _currentItemSelected = textList[0];
  }

  @override
  Widget build(BuildContext context) {
    return PopupMenuButton<String>(
      itemBuilder: (context) {
        return textList.map((str) {
          return PopupMenuItem(
            value: str,
            child: Text(str),
          );
        }).toList();
      },
      child: Row(
        mainAxisSize: MainAxisSize.min,
        children: <Widget>[
          Text(_currentItemSelected),
          Icon(Icons.arrow_drop_down),
        ],
      ),
      onSelected: (v) {
        setState(() {
          print('!!!===== $v');
          _currentItemSelected = v;
        });
      },
    );
  }
}

enter image description here


2
另一个解决方法是将其作为可点击文本,以对话框形式显示下拉选项。以下是示例: 预览GIF
import 'package:flutter/material.dart';

class CustomDialogTest extends StatefulWidget {
  @override
  _CustomDialogTestState createState() => _CustomDialogTestState();
}

class _CustomDialogTestState extends State<CustomDialogTest> {
  String _onDropDownItemSelected = '(Choose Option ▼)';

  var textList = [
    'Cat',
    'Dog',
    'Colorfull Unicorn',
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        title: Text(
          'Dropdown spacing',
        ),
      ),
      body: Padding(
        padding: EdgeInsets.only(top: 8.0),
        child: Container(
          color: Colors.white,
          child: Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              Text(
                'I am a ',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18,
                  fontWeight: FontWeight.w500,
                ),
              ),
              InkWell(
                onTap: () {
                  showDialog(
                    context: context,
                    child: Dialog(
                      backgroundColor: Colors.blue[100],
                      shape: RoundedRectangleBorder(
                        borderRadius: BorderRadius.circular(18.0),
                      ),
                      child: ListView.builder(
                          shrinkWrap: true,
                          itemCount: textList.length,
                          itemBuilder: (context, index) {
                            return GestureDetector(
                              child: Row(
                                children: <Widget>[
                                  Icon(
                                    Icons.arrow_right,
                                    color: Colors.black,
                                  ),
                                  Text(
                                    textList[index],
                                    style: TextStyle(
                                      color: Colors.black,
                                      fontSize: 20.0,
                                    ),
                                  ),
                                ],
                              ),
                              onTap: () {
                                Navigator.pop(context);
                                setState(() {
                                  _onDropDownItemSelected = textList[index];
                                });
                              },
                            );
                          }),
                    ),
                  );
                },
                child: Text(
                  _onDropDownItemSelected,
                  style: TextStyle(
                    color: Colors.blue[900],
                    fontSize: 18,
                    fontWeight: FontWeight.w500,
                  ),
                ),
              ),
              Text(
                ' Person',
                style: TextStyle(
                  color: Colors.black,
                  fontSize: 18,
                  fontWeight: FontWeight.w500,
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

你来得有点晚,但还是谢谢。我给你的答案点了赞,因为它也是有效的。 - CoderUni

1

结账 下拉按钮2

有一个customButton属性。 我用的一个例子。

 customButton: Row(
            children: [
              const Icon(
                Icons.plus_one,
                size: 12,
              ),
              Text(
                "References",
              )
            ],
          ),

选项框会扩展以适应行的大小。
编辑:发布后我意识到,它仍然受到无法比内部项目更小的限制。

Screenshot


0

使用 flexfit.loose 属性,下拉按钮内部的堆栈所占用的剩余空间将被切除。

Row(
  children: [
    Flexible(
      fit: FlexFit.loose,
      child: Padding(
        padding: const EdgeInsets.all(8),
        child: Container(
          decoration: BoxDecoration(
            border: Border.all(
              width: 2,
              color: Theme.of(context).primaryColor,
            ),
          ),
        child: Padding(
          padding: const EdgeInsets.only(left: 8.0, right: 8),
          child: DropdownButton(
            icon: const Icon(Icons.filter_alt),
            underline: Container(),
            hint: const Text(
              'Test',
              style: TextStyle(
                color: Colors.black,
              ),
            ),
          items: const [],
        ),
      ),
    ),
  ),
),
])

0

不行。如果你看代码的话

// The width of the button and the menu are defined by the widest
// item and the width of the hint.

如果必须的话(不建议这样做,因为您需要在底层代码更改时维护它),请克隆小部件并根据您的要求进行更改。


我该如何将它修改为符合我的需求?你能提供相关代码吗?抱歉,我之前从未编辑过Flutter的代码。当底层代码改变时,我可以很好地进行维护。 - CoderUni
这是源文件:https://github.com/flutter/flutter/blob/master/packages/flutter/lib/src/material/dropdown.dart,但请注意它导入了许多材料源文件。沿着这条路走将会是很多工作(并且会“破坏”材料设计)。 - Agreensh
你说得对。这会导致很多问题,而且代码很长,难以调试。不过还是谢谢你的回答。 - CoderUni

0
使用 DropdownButton 中的属性 `alignment`,您可以将文本对齐设置为 `centerRight`,从而产生期望的效果。
在 Flutter 2.12 上进行测试。
DropdownButton<String>(
                  value: dropdownValue,
                  elevation: 16,
                  underline: const SizedBox(),
                  isDense: true,
                  alignment: Alignment.centerRight,
)

enter image description here enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接