You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter技术问题:如何向已展开的Dropdown Menu添加选项?

解决Flutter Dropdown展开时实时更新选项的问题

默认的DropdownButton在菜单展开后,不会自动监听选项列表的变化,新增选项无法实时显示。这里提供两种可行的解决方案:

方案一:原生实现(无需第三方库)

通过GlobalKey控制Dropdown的内部状态,在选项更新时手动刷新展开的菜单:

import 'dart:async';
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('实时更新Dropdown选项')),
        body: const DropdownUpdateDemo(),
      ),
    );
  }
}

class DropdownUpdateDemo extends StatefulWidget {
  const DropdownUpdateDemo({super.key});

  @override
  State<DropdownUpdateDemo> createState() => _DropdownUpdateDemoState();
}

class _DropdownUpdateDemoState extends State<DropdownUpdateDemo> {
  final GlobalKey<DropdownButtonState<String>> _dropdownKey = GlobalKey();
  List<String> _items = ['选项1', '选项2'];
  String? _selectedItem;
  bool _isMenuOpen = false;
  late Timer _timer;

  @override
  void initState() {
    super.initState();
    // 每2秒添加新选项
    _timer = Timer.periodic(const Duration(seconds: 2), (timer) {
      setState(() {
        _items.add('选项${_items.length + 1}');
      });
      // 菜单展开时,先关闭再重新打开以刷新选项
      if (_isMenuOpen) {
        _dropdownKey.currentState?.close();
        Future.delayed(const Duration(milliseconds: 50), () {
          _dropdownKey.currentState?.showButtonMenu();
        });
      }
    });
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: DropdownButton<String>(
        key: _dropdownKey,
        value: _selectedItem,
        items: _items.map((item) => DropdownMenuItem(value: item, child: Text(item))).toList(),
        onChanged: (value) {
          setState(() {
            _selectedItem = value;
            _isMenuOpen = false;
          });
        },
        onTap: () => setState(() => _isMenuOpen = !_isMenuOpen),
      ),
    );
  }
}

核心逻辑:

  • 用GlobalKey获取DropdownButton的内部状态,调用close()和showButtonMenu()控制菜单显隐
  • 通过onTap事件跟踪菜单的展开状态
  • 选项更新时,若菜单处于展开状态,先关闭再重新打开,触发菜单重新渲染新选项

方案二:使用第三方库(更简洁流畅)

推荐使用dropdown_button2库,它原生支持展开状态下的选项实时更新,无需手动控制菜单:

首先在pubspec.yaml添加依赖:

dependencies:
  dropdown_button2: ^2.3.9

然后实现代码:

import 'dart:async';
import 'package:flutter/material.dart';
import 'package:dropdown_button2/dropdown_button2.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('实时更新Dropdown选项')),
        body: const DropdownUpdateDemo(),
      ),
    );
  }
}

class DropdownUpdateDemo extends StatefulWidget {
  const DropdownUpdateDemo({super.key});

  @override
  State<DropdownUpdateDemo> createState() => _DropdownUpdateDemoState();
}

class _DropdownUpdateDemoState extends State<DropdownUpdateDemo> {
  List<String> _items = ['选项1', '选项2'];
  String? _selectedItem;
  late Timer _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(const Duration(seconds: 2), (timer) {
      setState(() {
        _items.add('选项${_items.length + 1}');
      });
    });
  }

  @override
  void dispose() {
    _timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: DropdownButton2<String>(
        value: _selectedItem,
        items: _items.map((item) => DropdownMenuItem(value: item, child: Text(item))).toList(),
        onChanged: (value) => setState(() => _selectedItem = value),
      ),
    );
  }
}

优势:

  • 代码更简洁,无需额外控制逻辑
  • 菜单更新更流畅,没有关闭再打开的延迟感

内容的提问来源于stack exchange,提问作者coder19

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 13:32:13