Flutter DropdownButton 详解

目录

[1. 引言](#1. 引言)

[2. DropdownButton 的基本用法](#2. DropdownButton 的基本用法)

[3. 主要属性](#3. 主要属性)

[4. 自定义 DropdownButton](#4. 自定义 DropdownButton)

[4.1 组合 DropdownButton 与 InputDecoration](#4.1 组合 DropdownButton 与 InputDecoration)

[4.2 从列表动态生成选项](#4.2 从列表动态生成选项)

[4.3 异步数据加载(API 请求)](#4.3 异步数据加载(API 请求))

[4.4 按钮外观定制](#4.4 按钮外观定制)

[4.5 自定义下拉菜单](#4.5 自定义下拉菜单)

[4.6 多级联动下拉菜单](#4.6 多级联动下拉菜单)

[4.7 搜索过滤功能](#4.7 搜索过滤功能)

[5. 结论](#5. 结论)

相关推荐


1. 引言

DropdownButton 是 Flutter 中用于创建下拉菜单的组件,适用于表单选择、筛选项等场景。它允许用户从多个选项中选择一个,并支持自定义样式和交互逻辑。本文将介绍 DropdownButton 的基本用法、主要属性及其自定义方法。

DropdownButton 需要 value 指定当前选中项,并通过 onChanged 监听用户选择。

Dart 复制代码
String selectedValue = '选项2';
List<String> items = ['选项1', '选项2', '选项3'];

DropdownButton<String>(
  value: selectedValue,
  onChanged: (String? newValue) {
    setState(() {
      selectedValue = newValue!;
    });
  },
  items: items.map((String item) {
    return DropdownMenuItem<String>(
      value: item,
      child: Text(item),
    );
  }).toList(),
)

3. 主要属性

属性 说明
value 当前选中的值
items 下拉选项列表(必须是 DropdownMenuItem 列表)
onChanged 选项变更时的回调
hint 默认提示文本(未选择时显示)
disabledHint onChangednull 时的提示文本
icon 自定义下拉按钮的图标
underline 自定义下划线
style 文字样式
dropdownColor 下拉菜单背景颜色

示例:

Dart 复制代码
DropdownButton<String>(
  value: selectedValue,
  dropdownColor: Colors.blueAccent,
  style: TextStyle(color: Colors.white, fontSize: 16),
  underline: Container(height: 2, color: Colors.white),
  icon: Icon(Icons.arrow_drop_down, color: Colors.white),
  onChanged: (String? newValue) {
    setState(() {
      selectedValue = newValue!;
    });
  },
  items: items.map((String item) {
    return DropdownMenuItem<String>(
      value: item,
      child: Text(item),
    );
  }).toList(),
)

可以将 DropdownButton 嵌入 InputDecorator 以模拟表单输入框样式。

Dart 复制代码
InputDecorator(
  decoration: InputDecoration(
    labelText: '选择一个选项',
    border: OutlineInputBorder(),
  ),
  child: DropdownButtonHideUnderline(
    child: DropdownButton<String>(
      value: selectedValue,
      onChanged: (String? newValue) {
        setState(() {
          selectedValue = newValue!;
        });
      },
      items: items.map((String item) {
        return DropdownMenuItem<String>(
          value: item,
          child: Text(item),
        );
      }).toList(),
    ),
  ),
)

4.2 从列表动态生成选项

Dart 复制代码
final List<String> _list = ['苹果', '香蕉', '橘子', '葡萄'];
String? _selected;

DropdownButton<String>(
  value: _selected,
  items: _list.map((s) {
    return DropdownMenuItem(
      value: s,
      child: Text(fruit),
    );
  }).toList(),
  onChanged: (value) => setState(() => _selectedFruit = value),
)

4.3 异步数据加载(API 请求)

Dart 复制代码
FutureBuilder<List<String>>(
  future: _fetchFruitsFromApi(),
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.waiting) {
      return const CircularProgressIndicator();
    }
    if (snapshot.hasError) {
      return Text('加载失败: ${snapshot.error}');
    }
    return DropdownButton(
      items: snapshot.data!.map((fruit) => 
        DropdownMenuItem(value: fruit, child: Text(fruit))
      .toList(),
      onChanged: (value) {/*...*/},
    );
  },
)

4.4 按钮外观定制

Dart 复制代码
DropdownButton<String>(
  style: TextStyle(
    color: Colors.blue[800],
    fontSize: 16,
    fontWeight: FontWeight.w600
  ),
  dropdownColor: Colors.blue[50],  // 下拉菜单背景色
  icon: const Icon(Icons.arrow_drop_down_circle),
  iconSize: 24,
  iconEnabledColor: Colors.blue,
  underline: Container( // 移除默认下划线
    height: 0,
    color: Colors.transparent,
  ),
  // ...其他参数
)

4.5 自定义下拉菜单

Dart 复制代码
DropdownButton<String>(
  isExpanded: true, // 宽度撑满父容器
  menuMaxHeight: 300, // 最大高度
  itemHeight: 60,     // 单个选项高度
  selectedItemBuilder: (context) { // 选中态特殊样式
    return _fruitList.map((fruit) => 
      Text(fruit, style: const TextStyle(color: Colors.red))
    .toList();
  },
  // ...其他参数
)

4.6 多级联动下拉菜单

Dart 复制代码
// 省份-城市联动
String? _selectedProvince;
String? _selectedCity;

Column(
  children: [
    // 省份选择
    DropdownButton(
      value: _selectedProvince,
      items: provinces.map((province) => /*...*/),
      onChanged: (value) {
        setState(() {
          _selectedProvince = value;
          _selectedCity = null; // 重置城市选择
        });
      },
    ),
    // 动态城市列表
    if (_selectedProvince != null)
      DropdownButton(
        value: _selectedCity,
        items: cities[_selectedProvince]!.map((city) => /*...*/),
        onChanged: (value) => setState(() => _selectedCity = value),
      )
  ],
)

4.7 搜索过滤功能

Dart 复制代码
final TextEditingController _searchController = TextEditingController();

Widget build(BuildContext context) {
  return Column(
    children: [
      TextField(
        controller: _searchController,
        decoration: InputDecoration(
          hintText: '搜索水果...',
          prefixIcon: Icon(Icons.search)),
        onChanged: (value) => setState(() {}),
      ),
      DropdownButton(
        items: _fruitList
          .where((fruit) => fruit.contains(_searchController.text))
          .map((fruit) => DropdownMenuItem(...))
          .toList(),
        // ...其他参数
      )
    ],
  );
}

5. 结论

DropdownButton 是 Flutter 中用于选择单个选项的组件,适用于表单输入、筛选等场景。结合 DropdownMenuItem 可动态生成选项列表,并可通过 styleicondropdownColor 等属性进行自定义。掌握 DropdownButton 的使用,可以更好地优化应用的用户交互体验。

相关推荐

Flutter 输入组件 Checkbox 详解-CSDN博客文章浏览阅读725次,点赞26次,收藏10次。在 Flutter 中,Checkbox 是一个常用的多选组件,适用于设置开关选项、同意协议、筛选条件等场景。Checkbox 允许用户勾选或取消勾选,并可通过 value 和 onChanged 进行状态管理。本文将介绍 Checkbox 的基本用法、主要属性及自定义样式。https://shuaici.blog.csdn.net/article/details/146068557Flutter 输入组件 Radio 详解-CSDN博客文章浏览阅读920次,点赞24次,收藏30次。在 Flutter 中,Radio是用于单选的按钮组件,适用于需要用户在多个选项中选择一个的场景,如表单、设置选项等。Radio通过value和groupValue进行状态管理,并结合onChanged监听选中状态的变化。本文将介绍Radio的基本用法、主要属性及自定义样式。https://shuaici.blog.csdn.net/article/details/146068599

相关推荐
谢白羽1 天前
vllm实践
android·vllm
电子云与长程纠缠1 天前
Godot学习03 - 实例化、层级访问、Export
android·学习·godot
毕设源码-朱学姐1 天前
【开题答辩全过程】以 基于Android的便民系统的设计与实现为例,包含答辩的问题和答案
android
鬼蛟1 天前
Spring————事务
android·java·spring
不爱吃糖的程序媛1 天前
Flutter OH Engine构建指导
flutter
qq_170264751 天前
unity出安卓年龄分级的arr包问题
android·unity·游戏引擎
kejiashao1 天前
Android View的绘制流程及事件分发机制
android
小蜜蜂嗡嗡1 天前
flutter实现付费解锁内容的遮挡
android·flutter
进击的cc1 天前
拒绝背诵!一文带你打穿 Android ANR 发生的底层全链路
android·面试
进击的cc1 天前
App 启动优化全家桶:别再只盯着 Application 了,热启动优化你真的做对了吗?
android·面试