搜索插件、代码仓与 APP 分类

插件详情v0.0.2

defer_pointer

一种替代 Overlay 的方法,可轻松在父级边界之外渲染和命中测试小部件。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
8万
喜欢数
158
Pub 分数
130

安装插件

flutter pub add defer_pointer

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

defer_pointer 包提供了一种替代 Flutter 的 Overlay 的方法,使小部件能够在其父小部件边界之外进行渲染和交互。它简化了在 UI 层次结构中动态定位的小部件的命中测试,非常适合复杂的覆盖层、工具提示或需要响应指针事件的浮动元素,而无需考虑布局约束。该包由 gskinner.com 开发,支持所有主要平台,包括 Android、iOS、Web、macOS、Windows 和 Linux。该包增强了用户交互的灵活性,无需手动管理图层。

适合场景

  • 创建浮动提示
  • 构建动态叠加层
  • 在受限布局中实现拖放功能
  • 渲染超出父级边界的交互元素
  • 设计自定义指针敏感的UI组件

主要特点

  • 支持跨边界命中测试
  • 简化叠加层实现
  • 适用于所有 Flutter 平台
  • 所需的样板代码最少
  • 可无缝集成到现有的 widget 树中

适合对象

  • 开发复杂 UI 交互的开发者
  • 需要响应式覆盖层的团队
  • 具有动态浮动元素的应用程序
  • 需要高级指针处理的UI库
  • 面向多个平台的项目

使用建议

  • 可能会影响大量活动 widget 的性能
  • 需要仔细管理状态
  • 不适合用于简单的静态覆盖层
  • 除了基本用法外,文档有限
  • 如果未妥善管理,可能存在意外的指针捕获风险

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

An alternative to Overlay which allows you to easily render and hit test a widget outside its parent bounds. Based on the original idea by @shrouxm here: https://github.com/flutter/flutter/issues/75747#issuecomment-907755810

Typically in Flutter, if you offset a widget outside of it's parent bounds hit-testing will break. DeferPointer works around this issue by handing off hit-testing and (optionally) rendering to an DeferredPointerHandler widget further up the tree.

While Overlay can solve this issue to some degree, using DeferPointer offers some benefits:

  • just works: no error prone and tedious layer management
  • more granular: you can set the bounds to be any ancestor widget you choose
  • more flexible: you can choose to paint the child on top, or not
  • easier to align/pin to a widget in the tree as that is the default expectation

This is useful for larger UI components like dropdown menus and sliding panels, as well as just small general styling tweaks.

🔨 Installation

dependencies:
  defer_pointer: ^0.0.2
⚙ Import
import 'package:defer_pointer/defer_pointer.dart';

🕹️ Usage

  1. Wrap a DeferredPointerHandler somewhere above the buttons that you wish to hit-test.
  2. Wrap DeferPointer around the buttons themselves.
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),
                 ]),
               ),
             ),
           ]))));
  }

Enable paintOnTop if you need the child Widget painted on top of it's siblings. This will defer painting to the currently linked DeferredPointerHandler.

return DeferPointer(
    paintOnTop: true,
    child: TextButton(...));
Examples

There are 4 examples in this repo:

  1. A simple example of offsetting 2 buttons outside their stack: https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/simple_offset_outside_parent.dart

  2. A classic desktop/web style dropdown menu: https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/dropdown_menus.dart

  3. A animated menu based on the Flow widget: https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/flow_menu.dart

  4. A auto-complete search field: https://github.com/gskinnerTeam/flutter-defer-pointer/blob/master/example/lib/examples/auto_complete.dart

Manual Linking

By default a DeferPointer widget will look up the closest DeferredPointerHandler using it's current context. For more complicated use cases you can manually assign a link to bind a pointer to a handler:

final _deferredPointerLink = DeferredPointerHandlerLink();
...
Widget build(){
    return DeferredPointerHandler(
      link: _deferredPointerLink,
      child: Padding(
          padding: const EdgeInsets.all(20),
          child: DeferPointer(
            link: _deferredPointerLink,
            child: ...,
          )),
    );
}

🐞 Bugs/Requests

If you encounter any problems please open an issue. If you feel the library is missing a feature, please raise a ticket on Github and we'll look into it. Pull request are welcome.

📃 License

MIT License

所属分类

依赖

依赖清单 1 项

源码仓库

使用此插件的项目