如何创建带InkWell的特定样式Flutter下拉按钮
自定义Flutter下拉按钮实现
以下是符合需求的完整实现代码,包含自定义下拉触发区域、选中状态UI更新和选中项高亮:
import 'package:flutter/material.dart'; class CustomDropdown extends StatefulWidget { const CustomDropdown({super.key}); @override State<CustomDropdown> createState() => _CustomDropdownState(); } class _CustomDropdownState extends State<CustomDropdown> { // 选项列表 final List<String> options = ['选项1', '选项2', '选项3', '选项4']; // 保存选中的选项,初始为null表示未选择 String? selectedOption; @override Widget build(BuildContext context) { return Row( mainAxisSize: MainAxisSize.min, children: [ // 左侧文本 const Text('选择选项:'), const SizedBox(width: 8), // AssetImage(请确保已在pubspec.yaml中配置对应资源) Image.asset( 'assets/icon.png', width: 24, height: 24, ), const SizedBox(width: 8), // 下拉触发区域InkWell InkWell( onTap: () => _showOptionsMenu(context), child: Container( padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8), decoration: BoxDecoration( border: Border.all(color: Colors.grey), borderRadius: BorderRadius.circular(4), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ // 显示选中的文本或默认提示 Text( selectedOption ?? '请选择', style: TextStyle( color: selectedOption != null ? Colors.black : Colors.grey, ), ), const SizedBox(width: 8), // 根据选中状态切换图标 Icon( selectedOption != null ? Icons.check : Icons.arrow_drop_down, color: selectedOption != null ? Colors.green : Colors.grey, ), ], ), ), ), ], ); } // 弹出选项菜单 void _showOptionsMenu(BuildContext context) async { final RenderBox renderBox = context.findRenderObject() as RenderBox; final Offset offset = renderBox.localToGlobal(Offset.zero); final String? result = await showMenu<String>( context: context, position: RelativeRect.fromLTRB( offset.dx, offset.dy + renderBox.size.height, offset.dx + renderBox.size.width, offset.dy + renderBox.size.height + 200, ), items: options.map((option) { return PopupMenuItem<String>( value: option, child: Text( option, // 选中项显示红色 style: TextStyle( color: selectedOption == option ? Colors.red : Colors.black, ), ), ); }).toList(), ); // 更新选中状态 if (result != null) { setState(() { selectedOption = result; }); } } } // 用于测试的主函数 void main() => runApp(const MaterialApp(home: Scaffold(body: Center(child: CustomDropdown()))));
关键实现细节说明:
- 状态管理:通过
selectedOption变量跟踪选中的选项,调用setState更新UI - InkWell触发区域:自定义了带边框的容器,根据选中状态切换显示的文本和图标(未选时显示下拉箭头,选中时显示对勾)
- 弹出菜单:使用
showMenu方法在指定位置弹出选项列表,通过RelativeRect控制菜单的显示位置 - 选中项高亮:在
PopupMenuItem中判断当前选项是否为选中状态,若是则设置文本颜色为红色 - AssetImage配置:请确保在
pubspec.yaml中添加资源路径,示例配置如下:assets: - assets/icon.png
内容的提问来源于stack exchange,提问作者farhan khan
相关产品推荐
相关产品推荐

