DraggableFloatingWidget class

Positions its content via an internally-managed, user-draggable offset — defaulting near the bottom-right corner of the screen (or wherever defaultOffset says). Shared by DevToolsBubble and DevToolsFloatingWindow so both drag (and edge-peek) identically.

Must be used as a (possibly indirect) child of a Stack — it produces a Positioned from its own build method, and relies on the Stack's default hard-edge clipping to visually hide whatever part of it is dragged past the screen edge. builder gets onPanUpdate / onPanEnd callbacks to attach wherever dragging should be possible: the whole widget (a small bubble, say), or just a drag-handle sub-region (e.g. a header bar) so the rest of the content can scroll/tap normally without fighting the drag gesture.

Dragging past the left or right screen edge is allowed — up to peekExtent pixels remaining visible — so it visibly, continuously slides off-screen as you drag it there, the same real-time feedback Android's floating chat-bubble / floating-window widgets give. Releasing the drag then commits to fully peeking (leaving just peekExtent pixels visible) only if you've pushed it past the edge by at least commitThreshold of the available peek travel; otherwise it springs back to flush-at-the-edge, fully visible — so merely nudging it near the edge, or a little past it, doesn't hide it. Never having crossed the edge at all leaves it exactly where dropped, with no snap either way. Tapping a peeked sliver slides it back to fully visible (it doesn't also trigger the widget's own tap action — that would risk firing it by accident on the same tap that was really just "bring this back"). Dragging always works from the fully-visible state, regardless of which edge it's docked at.

The dragged content is built once and reused on every drag frame — only the Positioned offset itself updates per frame, via a ValueListenableBuilder rather than setState on this whole widget. For a small bubble that distinction barely matters, but the floating window's content is a full tab set (Network/Logs/Performance/Info); rebuilding all of that on every pixel of drag movement is exactly the kind of per-frame cost that reads as janky, laggy dragging.

Inheritance

Constructors

DraggableFloatingWidget({Key? key, required Size size, required Widget builder(BuildContext context, GestureDragUpdateCallback onPanUpdate, GestureDragEndCallback onPanEnd), Offset defaultOffset(Size screenSize, Size widgetSize)?, double commitThreshold = 0.5, double peekExtent = 28, BorderRadius borderRadius = BorderRadius.zero})
const

Properties

borderRadius BorderRadius
Clips the whole size bounding box to this shape. A rounded Material sized to exactly fill that box (as the floating window does) still leaves this box's own four corners uncovered — a rounded shape inscribed in a same-sized square doesn't reach into the square's corners — so anything painted behind it within this widget (the Overlay beneath the window's content clips to a hard rectangular edge by default) shows through there unless this outer box is rounded to match. Defaults to no rounding, since the bubble is already a circle with nothing behind it to leak through.
final
builder Widget Function(BuildContext context, GestureDragUpdateCallback onPanUpdate, GestureDragEndCallback onPanEnd)
final
commitThreshold double
How far past the edge a drag has to be released — as a fraction of the available peek travel (size.width - peekExtent) — to commit to fully peeking rather than springing back to flush-at-the-edge.
final
defaultOffset Offset Function(Size screenSize, Size widgetSize)?
Computes the initial position from the screen size and this widget's size; defaults to near the bottom-right corner.
final
hashCode int
The hash code for this object.
no setterinherited
key Key?
Controls how one widget replaces another widget in the tree.
finalinherited
peekExtent double
How many pixels remain visible when peeking at an edge.
final
runtimeType Type
A representation of the runtime type of the object.
no setterinherited
size Size
final

Methods

createElement() StatefulElement
Creates a StatefulElement to manage this widget's location in the tree.
inherited
createState() State<DraggableFloatingWidget>
Creates the mutable state for this widget at a given location in the tree.
override
debugDescribeChildren() List<DiagnosticsNode>
Returns a list of DiagnosticsNode objects describing this node's children.
inherited
debugFillProperties(DiagnosticPropertiesBuilder properties) → void
Add additional properties associated with the node.
inherited
noSuchMethod(Invocation invocation) → dynamic
Invoked when a nonexistent method or property is accessed.
inherited
toDiagnosticsNode({String? name, DiagnosticsTreeStyle? style}) DiagnosticsNode
Returns a debug representation of the object that is used by debugging tools and by DiagnosticsNode.toStringDeep.
inherited
toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) String
A string representation of this object.
inherited
toStringDeep({String prefixLineOne = '', String? prefixOtherLines, DiagnosticLevel minLevel = DiagnosticLevel.debug, int wrapWidth = 65}) String
Returns a string representation of this node and its descendants.
inherited
toStringShallow({String joiner = ', ', DiagnosticLevel minLevel = DiagnosticLevel.debug}) String
Returns a one-line detailed description of the object.
inherited
toStringShort() String
A short, textual description of this widget.
inherited

Operators

operator ==(Object other) bool
The equality operator.
inherited