Overlay 的一种替代方案,可让您轻松地在父级边界之外渲染和命中测试小部件。
基于 @shrouxm 的原创想法:https://github.com/flutter/flutter/issues/75747
通常在 Flutter 中,如果您将小部件偏移到其父级边界之外,命中测试将会中断。DeferPointer 通过将命中测试和(可选)渲染交给树中更靠上的 DeferredPointerHandler 小部件来解决此问题。
虽然 Overlay 可以在一定程度上解决此问题,但使用 DeferPointer 具有一些优势:
- 即插即用:无需易出错且繁琐的图层管理
- 更细粒度:您可以将边界设置为您选择的任何祖先小部件
- 更灵活:您可以选择在子级之上绘制,或者不绘制
- 更容易对齐/固定到树中的某个小部件,因为这是默认的期望
这对于下拉菜单和滑动面板等大型 UI 组件以及一些小的通用样式调整非常有用。
? 安装
dependencies:
defer_pointer: ^0.0.2
⚙ 导入
import 'package:defer_pointer/defer_pointer.dart';
?️ 用法
- 将
DeferredPointerHandler包装在您想要进行命中测试的按钮的上方某处。 - 将
DeferPointer包装在按钮本身周围。
Widget build(BuildContext context) {
return DeferredPointerHandler(
child: SizedBox(
width: 100,
height: 100,
child: Stack(clipBehavior: Clip.none, children: [
// Hang button off the bottom of the content
Positioned(
bottom: -30,
child: DeferPointer(child: _SomeBtn(false)),
),
// Content
Positioned.fill(
child: Container(
decoration: BoxDecoration(color: Colors.green, boxShadow: [
BoxShadow(color: Colors.black.withOpacity(1), blurRadius: 4, spreadRadius: 4),
]),
),
),
]))));
}
如果需要将子小部件绘制在其同级之上,请启用 paintOnTop。这将把绘制推迟到当前链接的 DeferredPointerHandler。
return DeferPointer(
paintOnTop: true,
child: TextButton(...));
示例
此仓库中包含 4 个示例
-
一个将 2 个按钮偏移到其堆栈之外的简单示例
https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/simple_offset_outside_parent.dart -
经典的桌面/网页风格下拉菜单
https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/dropdown_menus.dart -
基于
Flow小部件的动画菜单
https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/flow_menu.dart
手动链接
默认情况下,DeferPointer 小部件会使用其当前上下文查找最近的 DeferredPointerHandler。对于更复杂的用例,您可以手动分配链接来将指针绑定到处理程序
final _deferredPointerLink = DeferredPointerHandlerLink();
...
Widget build(){
return DeferredPointerHandler(
link: _deferredPointerLink,
child: Padding(
padding: const EdgeInsets.all(20),
child: DeferPointer(
link: _deferredPointerLink,
child: ...,
)),
);
}
? Bug/请求
如果您遇到任何问题,请打开一个 issue。如果您觉得库缺少某个功能,请在 Github 上提交一个 ticket,我们将进行审查。欢迎提交 Pull Request。
? 许可证
MIT 许可