Flutter中如何用下拉框实现年月日期选择器?
Flutter 年月下拉选择器实现方案
现成控件推荐
- 第三方包
dropdown_button2:支持高度自定义下拉内容,能快速实现年月组合的下拉选择器,无需从零开发。 - 原生
DropdownButton:Flutter自带控件,可通过组合两个下拉框(年、月)实现需求,适合不需要复杂样式的场景。
实现步骤
方案一:使用dropdown_button2第三方包
- 添加依赖到
pubspec.yaml:
dependencies: dropdown_button2: ^2.3.9 # 可替换为最新版本
- 示例代码:
import 'package:flutter/material.dart'; import 'package:dropdown_button2/dropdown_button2.dart'; class YearMonthPicker extends StatefulWidget { const YearMonthPicker({super.key}); @override State<YearMonthPicker> createState() => _YearMonthPickerState(); } class _YearMonthPickerState extends State<YearMonthPicker> { final List<String> _years = List.generate(21, (index) => (2010 + index).toString()); final List<String> _months = List.generate(12, (index) => (index + 1).toString().padLeft(2, '0')); String? _selectedYear; String? _selectedMonth; @override Widget build(BuildContext context) { return DropdownButtonHideUnderline( child: DropdownButton2( hint: const Text('选择年月'), items: [ DropdownMenuItem( value: 'year_month', child: Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ DropdownButton<String>( value: _selectedYear, hint: const Text('年'), items: _years.map((year) => DropdownMenuItem(value: year, child: Text(year))).toList(), onChanged: (value) => setState(() => _selectedYear = value), ), const Text('年'), DropdownButton<String>( value: _selectedMonth, hint: const Text('月'), items: _months.map((month) => DropdownMenuItem(value: month, child: Text(month))).toList(), onChanged: (value) => setState(() => _selectedMonth = value), ), const Text('月'), ], ), ), ], onChanged: (_) {}, buttonHeight: 40, buttonWidth: 150, itemHeight: 80, ), ); } }
方案二:原生DropdownButton组合实现
- 核心代码示例:
class NativeYearMonthPicker extends StatefulWidget { const NativeYearMonthPicker({super.key}); @override State<NativeYearMonthPicker> createState() => _NativeYearMonthPickerState(); } class _NativeYearMonthPickerState extends State<NativeYearMonthPicker> { final List<String> _years = List.generate(21, (index) => (2010 + index).toString()); final List<String> _months = List.generate(12, (index) => (index + 1).toString().padLeft(2, '0')); String? _selectedYear; String? _selectedMonth; @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ DropdownButton<String>( value: _selectedYear, hint: const Text('选择年'), items: _years.map((year) => DropdownMenuItem(value: year, child: Text('$year年'))).toList(), onChanged: (value) => setState(() => _selectedYear = value), ), const SizedBox(width: 8), DropdownButton<String>( value: _selectedMonth, hint: const Text('选择月'), items: _months.map((month) => DropdownMenuItem(value: month, child: Text('$month月'))).toList(), onChanged: (value) => setState(() => _selectedMonth = value), ), ], ); } }
自定义开发注意点
如果需要完全匹配设计图的样式,可自行封装Widget:
- 统一两个下拉框的边框、圆角、高度,让视觉上更像一个整体。
- 处理下拉菜单的弹出位置、样式,比如自定义菜单的背景色、文字样式。
- 添加年月联动逻辑(比如限制可选年份范围、月份随年份变化的特殊需求)。
内容的提问来源于stack exchange,提问作者Timothy
相关产品推荐
相关产品推荐

