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

snap 封面
插件详情v2.0.0

snap

一个功能强大的Flutter吸顶工具/组件,可实现非常灵活的吸顶管理以及在您的小部件之间进行吸顶。

AndroidiOSWebmacOSWindowsLinux
近 30 天下载
42
喜欢数
21
Pub 分数
140

安装插件

flutter pub add snap

插件介绍

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

Snap 是一个全面的 Flutter 包,为小部件提供灵活的吸附功能,可在各种布局中实现平滑且可自定义的吸附行为。它支持对吸附点、缓动动画和动态调整的精确控制,非常适合创建响应式、手势驱动的界面。该包可与可滚动小部件无缝集成,并提供对吸附位置和过渡效果的细粒度管理。专为寻求高级手势交互的开发者设计,Snap 能够在基于网格或卡片式的 UI 中提升用户体验。

适合场景

  • 创建可拖动的卡片布局
  • 实现滑动到定位的导航
  • 构建响应式网格界面
  • 设计交互式滑块
  • 启用带有吸附点的平滑滚动

主要特点

  • 灵活的快照点配置
  • 可自定义的动画曲线
  • 支持多个吸附目标
  • 动态吸附调整
  • 手势感知的吸附
  • 跨平台兼容性

适合对象

  • 开发交互式 UI 的开发者
  • 实现基于手势导航的设计人员
  • 需要精确控件对齐的应用程序
  • 使用可滚动网格或轮播图的项目
  • 专注于完善用户交互的团队

使用建议

  • 可能需要对复杂布局进行性能调优
  • 除了基本示例外,文档有限
  • 管理多个快照状态时可能出现的复杂性
  • 最适合中大型项目
  • 需要了解 Flutter 的手势系统

原始 README

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

snap

Cosmos Software Awesome Flutter

Pub License

An extensive snap tool/widget for Flutter that allows very flexible snap management and snapping between your widgets.

Inspired by WhatsApp's in-app Youtube player.

It is highly recommended to read the documentation and run the example project on a real device to fully understand and inspect the full range of capabilities.

Media | Description | How-to-Use

Notice

  • flick works as intended on actual devices even if it might appear to fail rarely on simulators. Don't be discouraged!

Recent

  • flick is now added. It is amazing! See Media for examples.

Media

Watch on Youtube:

v1.0.0 with Flick

v0.1.0



Description

This is an extensive snap tool/widget for Flutter that allows very flexible snap management and snapping between your widgets.

Just wrap your snapper widget with the SnapController widget, fill the parameters, define your snappable widget and this package will take care of everything else.

How-to-Use

"The view is what is being moved. It is the widget that snaps to the bound. The bound is what the view is being snapped to."

First, define two GlobalKeys- one for your view and one for your bound:

GlobalKey bound = GlobalKey();
GlobalKey view = GlobalKey();

Then, create a SnapController such as:

SnapController(
  uiChild(),                //uiChild
  false,                    //useCache
  view,                     //viewKey
  bound,                    //boundKey
  Offset.zero,              //constraintsMin
  const Offset(1.0, 1.0),   //constraintsMax
  const Offset(0.75, 0.75), //flexibilityMin
  const Offset(0.75, 0.75), //flexibilityMax
 {Key key,
  customBoundWidth  : 0,
  customBoundHeight : 0,
  snapTargets       : [
    const SnapTarget(Pivot.topLeft, Pivot.topLeft),
    const SnapTarget(Pivot.topRight, Pivot.topRight),
    const SnapTarget(Pivot.bottomLeft, Pivot.bottomLeft),
    const SnapTarget(Pivot.bottomRight, Pivot.bottomRight),
    const SnapTarget(Pivot.center, Pivot.center)
  ],
  animateSnap       : true,
  useFlick          : true,
  flickSensitivity  : 0.075,
  onMove            : _onMove,
  onDragStart       : _onDragStart,
  onDragUpdate      : _onDragUpdate,
  onDragEnd         : _onDragEnd,
  onSnap            : _onSnap})

Widget uiChild() {
  return Container(
    key: view,
    ...
  ); 
}

void _onMove(Offset offset);

void _onDragStart(dynamic dragDetails);
void _onDragUpdate(dynamic dragDetails);
void _onDragEnd(dynamic dragDetails);

void _onSnap(Offset offset);

Further Explanations:

For a complete set of descriptions for all parameters and methods, see the documentation.

  • Set [useCache] to true if your [uiChild] doesn't change during the Peek & Pop process.
  • Consider the following example:
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Expanded(
      child: Align(
        key: bound,
        alignment: const Alignment(-1.0, -1.0),
        child: SnapController(
          uiChild(),
          true,
          view,
          bound,
          Offset.zero,
          const Offset(1.0, 1.0),
          const Offset(0.75, 0.75),
          const Offset(0.75, 0.75),
          snapTargets: [
            const SnapTarget(Pivot.topLeft, Pivot.topLeft),
            const SnapTarget(Pivot.topRight, Pivot.topRight),
            const SnapTarget(Pivot.bottomLeft, Pivot.bottomLeft),
            const SnapTarget(Pivot.bottomRight, Pivot.bottomRight),
            const SnapTarget(Pivot.center, Pivot.center)
          ]
        )
      )
    )
  ]
)

In this excerpt, the bound is an Align widget which expands through a Column widget.

The SnapController is confined between Offset.zero and Offset(1.0, 1.0). This means the view will not exceed the limits of the bound.

The flexibility is confined between Offset(0.75, 0.75) and Offset(0.75, 0.75). This means that the view can be moved beyond the horizontal/vertical min/max constraints with a flexibility of 0.75 before it snaps.

The snapTargets determine from where and to where the view should snap once the movement is over. In this example:

  1. The top left corner of the view can snap to the top left corner of the bound.
  2. The top right corner of the view can snap to the top right corner of the bound.
  3. The bottom left corner of the view can snap to the bottom left corner of the bound.
  4. The bottom right corner of the view can snap to the bottom right corner of the bound.
  5. The center of the view can snap to the center of the bound.

Keep in mind that these constant values are provided only for the ease of use. snapTargets can consist of any values you wish.

  • Use [SnapControllerState]'s [bool isMoved(double treshold)] method to determine if the view is moved or not where [treshold] is the distance at which the view should be considered to be moved.

Notes

I started using and learning Flutter only some weeks ago so this package might have some parts that don't make sense, that should be completely different, that could be much better, etc. Please let me know! Nicely!

Any help, suggestion or criticism is appreciated!

Cheers.





所属分类

依赖

依赖清单 1 项

  • flick^2.0.0

源码仓库

使用此插件的项目

暂无相关数据。