如何在Flutter中实现支持多选的悬浮自定义下拉选择框
问题1:下拉框位置调整
你已经实现了findDropdownData方法获取触发控件的坐标,只要做两处修改即可:
- 打开Overlay前先调用方法获取坐标
- 给
Positioned的top属性赋值为y! + 50.h(50.h是你下拉触发框的高度,刚好让展开面板接在触发框下方)
修改dropdown组件的点击逻辑:
onTap: () { setState(() { isPressed = !isPressed; }); if (isPressed == false) { findDropdownData(); // 新增这行,先获取触发控件坐标 overlayEntry = _overlayEntryBuilder(); Overlay.of(context)!.insert(overlayEntry!); } }
修改_overlayEntryBuilder中的定位参数:
Positioned( top: y! + 50.h, // 取消注释,赋值为触发框y坐标+触发框高度 left: 16.w, right: 16.w, child: Material( child: dropdownExpanded(), ), )
问题2:Overlay中状态不更新
OverlayEntry的构建逻辑独立于当前页面的State,你调用当前页面的setState只会刷新当前页面的Widget树,不会触发OverlayEntry重新构建,所以状态变了但面板没刷新。
解决方法很简单:在Checkbox的onChanged里,调用setState之后额外调用overlayEntry?.markNeedsBuild()通知OverlayEntry刷新即可。
修改buildRows中Checkbox的点击逻辑:
onChanged: (value) { setState(() { booles[i] = value!; booles[i] == true ? picked.add(sports[i]) : picked.remove(sports[i]); }); overlayEntry?.markNeedsBuild(); // 新增这行,通知Overlay刷新 },
额外优化点:关闭下拉框时把overlayEntry置空,避免空调用风险:
onTap: () { setState(() { isPressed = !isPressed; }); overlayEntry?.remove(); overlayEntry = null; // 新增这行,置空实例 },
内容的提问来源于stack exchange,提问作者Milos
相关产品推荐
相关产品推荐

