У меня проблема с переполнением списка элементов в раскрывающемся меню (печать ниже). Я пытаюсь найти способ определить размер шрифта или применить переполнение. Я следил за документом Flutter здесь: https://api.flutter.dev/flutter/material/DropdownMenu-class.html
Пользователь может ввести текст и выполнить поиск или просто выбрать элемент из меню... Все элементы берутся из метки перечисления... как я могу его стилизовать (изменить размер шрифта, справиться с переполнением и т. д.)?
import 'package:flutter/material.dart';
/*-------Lista apenas de exemplo para o dropdown das malhas-------*/
enum MalhaLabel {
malha1('010 dime: omissão de entrega'),
malha2('NF-e: Cálculo: ');
const MalhaLabel(this.label);
final String label;
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController malhaController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(70.0),
/*-------AppBar com título-------*/
child: AppBar(
titleSpacing: 0.00,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
icon: const Icon(Icons.filter_alt_outlined),
);
},
),
title: const Text(
'AUDITORIA | MALHAS FISCAIS',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
backgroundColor: const Color(0xFF1C5D22),
),
),
/*-------Drawer com filtros-------*/
drawer: Container(
width: 350,
child: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const SizedBox(
height: 90.0,
child: DrawerHeader(
decoration: BoxDecoration(
color: Color(0xFF1C5D22),
),
child: Row(
children: [
Icon(
Icons.filter_alt_outlined,
color: Colors.white,
),
SizedBox(
width: 16,
),
Text(
'FILTROS',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
/*-------Filtros-------*/
Padding(
padding: const EdgeInsets.only(bottom: 20, top: 20),
child: ListTile(
title: const Text(
'Malhas fiscais:',
style: TextStyle(fontSize: 16),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 8),
child: DropdownMenu<MalhaLabel>(
controller: malhaController,
enableFilter: true,
requestFocusOnTap: true,
hintText: 'Digite e selecione',
dropdownMenuEntries:
MalhaLabel.values.map<DropdownMenuEntry<MalhaLabel>>(
(MalhaLabel malha) {
return DropdownMenuEntry<MalhaLabel>(
value: malha,
label: malha.label,
);
},
).toList(),
),
),
),
),
],
),
),
),
);
}
}





Попробуйте приведенный ниже фрагмент для раскрывающегося списка,
DropdownButton(
isExpanded: true,
value: selectedValue,
onChanged: (newValue) {
//LOGIC HERE
},
items: items.map((item) {
return DropdownMenuItem(
value: item,
child: Text(item, overflow: TextOverflow.ellipsis, maxLines: 1),
);
}).toList(),
),
Приятного коддинга..!
Я обновил предыдущую версию для использования DropdownMenu и настроил текст подсказки и элементы раскрывающегося меню. Кроме того, я выделил несколько стилей настройки в отдельные функции:
TextStyle get _fieldStyle {
return const TextStyle(
color: Colors.deepPurple,
fontSize: 18,
);
}
TextStyle get _itemStyle {
return const TextStyle(
fontSize: 16,
color: Colors.purple,
fontWeight: FontWeight.w300,
);
}
Обратите внимание на настройку текста подсказки и пунктов раскрывающегося меню, а также особое внимание к MenuStyle? menuStyle и ButtonStyle? style для дополнительных элементов управления стилем.
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: DropdownDrawerScreen(),
);
}
}
class DropdownDrawerScreen extends StatefulWidget {
const DropdownDrawerScreen({super.key});
@override
State<DropdownDrawerScreen> createState() => _DropdownDrawerScreenState();
}
class _DropdownDrawerScreenState extends State<DropdownDrawerScreen> {
final fruitController = TextEditingController();
String? selectedFruitName;
final List<String> fruits = [
'Apples are sweet and very crunchy, perfect for a healthy snack',
'Bananas are yellow, rich in potassium, and ideal for breakfast',
'Cherries are small, red, absolutely delicious, and great for making pies',
'Dates are sweet, chewy, very nutritious, and excellent for energy bars',
'Elderberries are dark, tart, and good for syrups, with strong antioxidant properties'
];
TextStyle get _fieldStyle {
return const TextStyle(
color: Colors.deepPurple,
fontSize: 18,
);
}
TextStyle get _itemStyle {
return const TextStyle(
fontSize: 16,
color: Colors.purple,
fontWeight: FontWeight.w300,
);
}
@override
void dispose() {
fruitController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Dropdown in Drawer Example')),
body: const Center(child: Text('Choose an option from the drawer')),
drawer: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const DrawerHeader(
decoration: BoxDecoration(color: Colors.blue),
child: Text(
'Choose a fruit',
style: TextStyle(color: Colors.white, fontSize: 24),
),
),
_buildMenu(),
OutlinedButton(
onPressed: () => fruitController.clear(),
child: const Text('Clear'),
)
],
),
),
);
}
Widget _buildMenu() {
return LayoutBuilder(builder: (_, ctx) {
final size = ctx.biggest;
final width = size.width;
return DropdownMenu<String>(
controller: fruitController,
label: _buildHintText(),
textStyle: _fieldStyle,
enableFilter: true,
requestFocusOnTap: true,
expandedInsets: EdgeInsets.zero,
menuStyle: MenuStyle(
fixedSize: MaterialStatePropertyAll(size),
),
width: width,
onSelected: (String? value) {
setState(() {
selectedFruitName = value;
});
},
dropdownMenuEntries: fruits.map((value) {
return DropdownMenuEntry<String>(
value: value,
label: value,
labelWidget: Row(
children: [Expanded(child: _buildItemText(value))],
),
style: ButtonStyle(
fixedSize: MaterialStatePropertyAll(size),
),
);
}).toList(),
);
});
}
Widget _buildHintText() {
return Text(
'Select your favorite fruit',
style: TextStyle(color: Colors.purple[100], fontSize: 16),
);
}
Widget _buildItemText(String value) {
return Container(
margin: const EdgeInsets.only(bottom: 8),
padding: const EdgeInsets.fromLTRB(4, 8, 4, 8),
decoration: BoxDecoration(
border: Border.all(color: Colors.black38),
borderRadius: BorderRadius.circular(8),
),
child: Text(
value,
style: _itemStyle,
),
);
}
}
Я использую DropdownMenu, а не DropdownButton. как образец документации флаттера: api.flutter.dev/flutter/material/DropdownMenu-class.html
Я отредактировал этот ответ
Вы, вероятно, не заметили, что есть дополнительный виджет, который вы можете передать в качестве параметра внутри.
DropdownMenuEntry<MalhaLabel>(
labelWidget:
)
Здесь вы можете настроить ширину и высоту, необходимую для устранения переполнения пикселей. Если вы хотите, чтобы текст истекал после определенного количества символов, вы можете сделать это внутри этого текста.
return DropdownMenuEntry<MalhaLabel>(
value: malha,
labelWidget: SizedBox(
width: MediaQuery.of(context).size.width * 0.90,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
malha.label,
),
)),
label: malha.label,
);
Вот ваш полный код с моей расширенной версией: скопируйте/вставьте его. Все работает нормально.
import 'package:flutter/material.dart';
/*-------Lista apenas de exemplo para o dropdown das malhas-------*/
enum MalhaLabel {
malha1('010 dime: omissão de entrega'),
malha2('NF-e: Cálculo: '),
malha3('NF-e: Cálculo:'),
malha4('NF-e: Cálculo2: omissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entrega'),
malha5('NF-e: Cálculo2: omissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entregaomissão de entrega');
const MalhaLabel(this.label);
final String label;
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
final TextEditingController malhaController = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: PreferredSize(
preferredSize: const Size.fromHeight(70.0),
/*-------AppBar com título-------*/
child: AppBar(
titleSpacing: 0.00,
leading: Builder(
builder: (BuildContext context) {
return IconButton(
onPressed: () {
Scaffold.of(context).openDrawer();
},
icon: const Icon(Icons.filter_alt_outlined),
);
},
),
title: const Text(
'AUDITORIA | MALHAS FISCAIS',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
backgroundColor: const Color(0xFF1C5D22),
),
),
/*-------Drawer com filtros-------*/
drawer: Container(
width: 350,
child: Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
const SizedBox(
height: 90.0,
child: DrawerHeader(
decoration: BoxDecoration(
color: Color(0xFF1C5D22),
),
child: Row(
children: [
Icon(
Icons.filter_alt_outlined,
color: Colors.white,
),
SizedBox(
width: 16,
),
Text(
'FILTROS',
style: TextStyle(
color: Colors.white,
fontSize: 18,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
/*-------Filtros-------*/
Padding(
padding: const EdgeInsets.only(bottom: 20, top: 20),
child: ListTile(
title: const Text(
'Malhas fiscais:',
style: TextStyle(fontSize: 16),
),
subtitle: Padding(
padding: const EdgeInsets.only(top: 8),
child: DropdownMenu<MalhaLabel>(
controller: malhaController,
enableFilter: true,
requestFocusOnTap: true,
hintText: 'Digite e selecione',
dropdownMenuEntries:
MalhaLabel.values.map<DropdownMenuEntry<MalhaLabel>>(
(MalhaLabel malha) {
return DropdownMenuEntry<MalhaLabel>(
value: malha,
labelWidget: SizedBox(
width: MediaQuery.of(context).size.width * 0.90,
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Text(
malha.label,
),
),),
label: malha.label,
);
},
).toList(),
),
),
),
),
],
),
),
),
);
}
}
Здравствуйте, сэр, спасибо за ответ, но это все равно не помогло. Он подчеркивает красную линию «labelWidget» и говорит: Именованный параметр «labelWidget» не определен. Попробуйте исправить имя на имя существующего именованного параметра или определить именованный параметр с именем «labelWidget».dartundefined_named_parameter
Я дал полный код, вы можете проверить его сейчас.
Еще раз спасибо, Абдул, я копирую и вставляю, но все равно получаю то же самое. Он подчеркивает красную линию под labelWidget... с ошибкой... что это может быть?
В моем случае он отображается отлично. Без каких-либо проблем. Проверьте этот импорт (import 'package:flutter/material.dart';).
Я использую DropdownMenu, а не DropdownButton. как образец документации Flutter: api.flutter.dev/flutter/material/DropdownMenu-class.html