'In Flutter, How can I make a widget "hover and follow" another widget in a Stack, without latency?
My demand is demonstrated in the following pic, I need the hovering box to "overflow" the underlying box:
My current implementation is to use Stack and Positioned.fromRect, get the Rect using the global key of item, then while it scroll I call setState to refresh it.
Stack(
children: [
ListView.builder(
controller: _controller,
physics: NoFlingScrollPhysics(),
itemBuilder: (context, index) {
return Center(
child: GestureDetector(
onTap: () {
setState(() {
selectedIndex = index;
});
},
child: RectGetter(
key: keys[index],
child: SizedBox.square(
dimension: MediaQuery.of(context).size.width / 2,
child: Container(
alignment: Alignment.center,
decoration: BoxDecoration(color: Colors.green, border: Border.all(color: Colors.black)),
child: Text(index.toString())),
))),
);
},
itemCount: 20,
),
Positioned.fromRect(
rect: rect,
child: GestureDetector(
behavior: HitTestBehavior.deferToChild,
onTap: () => toggleColor(),
onVerticalDragUpdate: (update) {
_controller
.jumpTo(_controller.offset - update.delta.dy);
},
child: Container(color: color)))
],
),
getRect(int? index) {
if (index == null) return Rect.zero;
var rect = RectGetter.getRectFromKey(keys[index]);
rect = rect?.inflate(10);
return rect ?? Rect.zero;
}
Rect get rect => getRect(selectedIndex);
However this method is laggy, it noticeably rubberbands while I scroll. Are there any better solution regarding this feature demand?
I am aware of inline OverflowBox solution (The items in ListView have OverflowBox in them), but the overflowing parts of it cannot be hit-tested by flutter's internal design, which is against my needs.
Solution 1:[1]
Thanks to @pskink, CompositedTransformTarget / CompositedTransformFollower is the solution.
TLDR: If HitTest/GestureDetector is needed on the "overflowing parts", and its position and size is dynamic, always use Overlay + CompositedTransformFollower!
See DartPad of my implementation
Explanation: Stack is Overlay under the hood, however Stack trades flexibility for convenience.
CompositedTransformTarget/CompositedTransformFollower pair can be used in Overlay to link Widgets in different layers by their position and align them with targetAnchor/followerAnchor parameter in the Follower widget.
The Follower can also get the size of its Target by accessing LayerLink#leaderSize.
This method does not incur the no-HitTest issue of OverflowBox either.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Linkfting |

