DEV Community

AR Rahman
AR Rahman

Posted on

Can you connect two widget in Flutter using LayerLink?

LinkLayer PopupLayerLink 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)
Enter fullscreen mode Exit fullscreen mode

Why It's Needed in Your Popup

In your case, you have:

  1. Button in the main widget tree (scrollable content)
  2. 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(),
              ),
            ),
          ),
        ],
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

What Happens During Scrolling

  1. User scrolls → Button moves within the scrollable area
  2. CompositedTransformTarget detects position changes
  3. LayerLink automatically updates the connection
  4. CompositedTransformFollower receives new position data
  5. Popup menu moves to maintain relative position to the button

Visual Example

Before Scroll:
┌─────────────────────┐
│ [Button]            │
│                     │
│ ┌─────────────────┐ │
│ │     Popup       │ │
│ └─────────────────┘ │
│                     │
└─────────────────────┘

After Scroll Down:
┌─────────────────────┐
│                     │
│                     │
│ [Button]            │
│ ┌─────────────────┐ │
│ │     Popup       │ │
│ └─────────────────┘ │
└─────────────────────┘
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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 ✓
Enter fullscreen mode Exit fullscreen mode

With LayerLink:

// Popup follows the button dynamically
CompositedTransformFollower(
  link: _layerLink,
  offset: Offset(0, 40),
  child: PopupMenu(),
)
// When scrolling: Popup moves with the button ✓
Enter fullscreen mode Exit fullscreen mode

Real-World Analogies

  1. Magnets: Like two magnets that stay connected even when you move one
  2. Parent-Child Leash: Like a parent holding a child's hand - when parent moves, child follows
  3. 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,
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

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)