Как стилизовать шрифт в элементах DropdownMenu Flutter

У меня проблема с переполнением списка элементов в раскрывающемся меню (печать ниже). Я пытаюсь найти способ определить размер шрифта или применить переполнение. Я следил за документом 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(),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
316
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Попробуйте приведенный ниже фрагмент для раскрывающегося списка,

      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, а не DropdownButton. как образец документации Flutter: api.flutter.dev/flutter/material/DropdownMenu-class.html

Felipe Machado 22.02.2024 14:21

Я обновил предыдущую версию для использования 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

Felipe Machado 22.02.2024 14:21

Я отредактировал этот ответ

OKJI 22.02.2024 16:53
Ответ принят как подходящий

Вы, вероятно, не заметили, что есть дополнительный виджет, который вы можете передать в качестве параметра внутри.

 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

Felipe Machado 22.02.2024 17:43

Я дал полный код, вы можете проверить его сейчас.

Abdul Awal 22.02.2024 18:29

Еще раз спасибо, Абдул, я копирую и вставляю, но все равно получаю то же самое. Он подчеркивает красную линию под labelWidget... с ошибкой... что это может быть?

Felipe Machado 22.02.2024 19:39

В моем случае он отображается отлично. Без каких-либо проблем. Проверьте этот импорт (import 'package:flutter/material.dart';).

Abdul Awal 23.02.2024 12:28

Другие вопросы по теме