LayerLink
is a powerful Flutter concept that enables precise widget positioning. Let me break it down:
What is LayerLink?
LayerLink
creates a connection between two parts of the widget tree that might be in different contexts (like between a widget and an overlay). It's part of Flutter's composited layers system.
How It Works
Think of it as an "invisible string" that connects two widgets:
CompositedTransformTarget (source) ← LayerLink → CompositedTransformFollower (follower)
Why It's Needed in Your Popup
In your case, you have:
- Button in the main widget tree (scrollable content)
- Popup menu in the Overlay (fixed screen position)
Without LayerLink
, when you scroll, the button moves but the popup stays in the same screen position.
The Magic: How It Maintains Position
class _InlineFilterPopupState extends State<InlineFilterPopup> {
final LayerLink _layerLink = LayerLink(); // ← Creates the link
final GlobalKey _iconKey = GlobalKey();
@override
Widget build(BuildContext context) {
return CompositedTransformTarget( // ← Source widget
link: _layerLink, // ← Connect the link
child: IconButton(
key: _iconKey,
icon: const Icon(Icons.filter_list),
onPressed: _toggleMenu,
),
);
}
void _showMenu() {
_overlayEntry = OverlayEntry(
builder: (context) => Stack(
children: [
Positioned(
child: CompositedTransformFollower( // ← Follower widget
link: _layerLink, // ← Same link connection
showWhenUnlinked: false,
offset: Offset(0, 40), // Position relative to target
child: Material(
// Your popup menu content
child: _buildMenuContent(),
),
),
),
],
),
);
}
}
What Happens During Scrolling
- User scrolls → Button moves within the scrollable area
- CompositedTransformTarget detects position changes
- LayerLink automatically updates the connection
- CompositedTransformFollower receives new position data
- Popup menu moves to maintain relative position to the button
Visual Example
Before Scroll:
┌─────────────────────┐
│ [Button] │
│ │
│ ┌─────────────────┐ │
│ │ Popup │ │
│ └─────────────────┘ │
│ │
└─────────────────────┘
After Scroll Down:
┌─────────────────────┐
│ │
│ │
│ [Button] │
│ ┌─────────────────┐ │
│ │ Popup │ │
│ └─────────────────┘ │
└─────────────────────┘
The popup automatically follows the button!
Key Properties
showWhenUnlinked
-
true
: Follower shows even when target is not in tree -
false
: Follower hides when target is not available
offset
Relative position from the target:
offset: Offset(0, 40) // 0px right, 40px down from button
offset: Offset(-20, 0) // 20px left, same vertical position
Without LayerLink vs With LayerLink
Without LayerLink:
// Popup stays at fixed screen coordinates
Positioned(
top: 100, // Fixed position
left: 100,
child: PopupMenu(),
)
// When scrolling: Button moves, popup stays in place ✓
With LayerLink:
// Popup follows the button dynamically
CompositedTransformFollower(
link: _layerLink,
offset: Offset(0, 40),
child: PopupMenu(),
)
// When scrolling: Popup moves with the button ✓
Real-World Analogies
- Magnets: Like two magnets that stay connected even when you move one
- Parent-Child Leash: Like a parent holding a child's hand - when parent moves, child follows
- GPS Tracker: Always knows the current position of the target
Technical Deep Dive
Under the hood, LayerLink
uses Flutter's CompositedTransformTargetLayer
and CompositedTransformFollowerLayer
:
// Simplified internal implementation
class CompositedTransformTarget extends SingleChildRenderObjectWidget {
final LayerLink link;
@override
RenderObject createRenderObject(BuildContext context) {
return RenderCompositedTransformTarget(
link: link,
);
}
}
class CompositedTransformFollower extends SingleChildRenderObjectWidget {
final LayerLink link;
final Offset offset;
@override
RenderObject createRenderObject(BuildContext context) {
return RenderCompositedTransformFollower(
link: link,
offset: offset,
);
}
}
When to Use LayerLink
Use LayerLink
when you need:
- ✅ Popups that follow scrolling content
- ✅ Tooltips attached to moving elements
- ✅ Custom dropdown menus in scrollable areas
- ✅ Any "attached" UI that should move with its parent
When NOT to Use LayerLink
Don't use when:
- ❌ Simple fixed-position overlays
- ❌ Modal dialogs that should center on screen
- ❌ UI elements that shouldn't move with content
Summary
LayerLink
is essentially a "live positioning cable" that:
- Connects two widgets in different parts of the tree
- Automatically updates positions during layout changes
- Enables advanced UI patterns like following popups
- Uses Flutter's compositing layer system for performance
Top comments (0)