Flutter中调整DropdownMenuItem宽度适配IP地址单行显示
问题解决方案
问题核心在于DropdownButton被限制在窄宽度容器中,导致下拉菜单继承了该窄宽度,IP地址被迫换行。以下是具体修复方案:
1. 核心修改点
移除DropdownButton的宽度限制
原代码中DropdownButton被包裹在SizedBox(width:50)中,直接导致下拉菜单宽度被压缩。去掉该限制,让按钮仅占用图标所需空间。
指定下拉菜单宽度
通过DropdownButton的menuWidth属性,设置下拉菜单宽度与外层TextField容器(200px)一致,或者通过LayoutBuilder动态获取父容器宽度实现适配。
强制文本单行显示
给DropdownMenuItem中的Text添加softWrap: false,避免自动换行;可选添加overflow: TextOverflow.ellipsis处理超出部分的显示。
修改后的完整代码
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class HistoryTextField extends StatefulWidget { final String fieldType; final String hintText; const HistoryTextField( {super.key, required this.fieldType, required this.hintText}); @override State<HistoryTextField> createState() => _HistoryTextFieldState(); } class _HistoryTextFieldState extends State<HistoryTextField> { final TextEditingController _controller = TextEditingController(); final List<String> _history = []; String? _selectedHistory; @override void initState() { super.initState(); _loadHistory(); } @override void dispose() { _controller.dispose(); super.dispose(); } Future<void> _loadHistory() async { final preferences = await SharedPreferences.getInstance(); setState(() { _history.addAll(preferences.getStringList(widget.fieldType) ?? []); if (_history.isNotEmpty) { _selectedHistory = _history.first; _controller.text = _selectedHistory!; } }); } Future<void> _saveHistory() async { final preferences = await SharedPreferences.getInstance(); preferences.setStringList(widget.fieldType, _history); } void _addToHistory(String text) { if (text.isNotEmpty && !_history.contains(text)) { _history.insert(0, text); _saveHistory(); } } @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { return Container( decoration: BoxDecoration( color: Theme.of(context).scaffoldBackgroundColor, border: Border.all(color: Theme.of(context).dividerColor), borderRadius: BorderRadius.circular(5), ), padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 4), child: Row( children: [ Expanded( child: TextField( cursorColor: Theme.of(context).dividerColor, decoration: InputDecoration( border: InputBorder.none, hintText: widget.hintText), controller: _controller, onChanged: (value) { setState(() { _selectedHistory = null; }); }, onSubmitted: (value) { _addToHistory(value); }, ), ), DropdownButtonHideUnderline( child: DropdownButton<String>( isExpanded: false, menuWidth: constraints.maxWidth, value: _selectedHistory, onChanged: (String? newValue) { setState(() { _selectedHistory = newValue; _controller.text = newValue!; }); }, selectedItemBuilder: (BuildContext context) { return _history.map<Widget>((String value) { return Container(); }).toList(); }, items: _history.map<DropdownMenuItem<String>>((String value) { return DropdownMenuItem<String>( value: value, child: Text( value, textAlign: TextAlign.left, softWrap: false, overflow: TextOverflow.ellipsis, ), ); }).toList(), icon: const Icon(Icons.arrow_drop_down), ), ), ], ), ); }, ); } }
说明
- 使用
LayoutBuilder动态获取父容器宽度,让下拉菜单宽度自动匹配外层TextField的容器宽度,避免硬编码数值 softWrap: false强制文本单行显示,overflow: TextOverflow.ellipsis确保超出部分显示省略号(若需完整显示可改为TextOverflow.visible,但下拉菜单宽度会自适应内容)- 移除了限制DropdownButton宽度的SizedBox,仅保留下拉图标所需空间
内容的提问来源于stack exchange,提问作者Geo48
相关产品推荐
相关产品推荐

