@@ -2104,14 +2104,41 @@ class PhysicalModelLayer extends ContainerLayer {
21042104/// * [RenderLeaderLayer] and [RenderFollowerLayer] , the corresponding
21052105/// render objects.
21062106class LayerLink {
2107- /// The currently-registered [LeaderLayer] , if any.
2108- LeaderLayer ? get leader => _leader;
21092107 LeaderLayer ? _leader;
21102108
2111- /// The total size of [leader] 's contents.
2109+ int _connectedFollowers = 0 ;
2110+
2111+ /// Whether a [LeaderLayer] is currently connected to this link.
2112+ bool get leaderConnected => _leader != null ;
2113+
2114+ /// Called by the [FollowerLayer] to establish a link to a [LeaderLayer] .
2115+ ///
2116+ /// The returned [LayerLinkHandle] provides access to the leader via
2117+ /// [LayerLinkHandle.leader] .
2118+ ///
2119+ /// When the [FollowerLayer] no longer wants to follow the [LeaderLayer] ,
2120+ /// [LayerLinkHandle.dispose] must be called to disconnect the link.
2121+ _LayerLinkHandle _registerFollower () {
2122+ assert (_connectedFollowers >= 0 );
2123+ _connectedFollowers++ ;
2124+ return _LayerLinkHandle (this );
2125+ }
2126+
2127+ /// Returns the [LeaderLayer] currently connected to this link.
2128+ ///
2129+ /// Valid in debug mode only. Returns null in all other modes.
2130+ LeaderLayer ? get debugLeader {
2131+ LeaderLayer ? result;
2132+ if (kDebugMode) {
2133+ result = _leader;
2134+ }
2135+ return result;
2136+ }
2137+
2138+ /// The total size of the content of the connected [LeaderLayer] .
21122139 ///
21132140 /// Generally this should be set by the [RenderObject] that paints on the
2114- /// registered [leader] layer (for instance a [RenderLeaderLayer] that shares
2141+ /// registered [LeaderLayer] (for instance a [RenderLeaderLayer] that shares
21152142 /// this link with its followers). This size may be outdated before and during
21162143 /// layout.
21172144 Size ? leaderSize;
@@ -2120,6 +2147,30 @@ class LayerLink {
21202147 String toString () => '${describeIdentity (this )}(${ _leader != null ? "<linked>" : "<dangling>" })' ;
21212148}
21222149
2150+ /// A handle provided by [LayerLink.registerFollower] to a calling
2151+ /// [FollowerLayer] to establish a link between that [FollowerLayer] and a
2152+ /// [LeaderLayer] .
2153+ ///
2154+ /// If the link is no longer needed, [dispose] must be called to disconnect it.
2155+ class _LayerLinkHandle {
2156+ _LayerLinkHandle (this ._link);
2157+
2158+ LayerLink ? _link;
2159+
2160+ /// The currently-registered [LeaderLayer] , if any.
2161+ LeaderLayer ? get leader => _link! ._leader;
2162+
2163+ /// Disconnects the link between the [FollowerLayer] owning this handle and
2164+ /// the [leader] .
2165+ ///
2166+ /// The [LayerLinkHandle] becomes unusable after calling this method.
2167+ void dispose () {
2168+ assert (_link! ._connectedFollowers > 0 );
2169+ _link! ._connectedFollowers-- ;
2170+ _link = null ;
2171+ }
2172+ }
2173+
21232174/// A composited layer that can be followed by a [FollowerLayer] .
21242175///
21252176/// This layer collapses the accumulated offset into a transform and passes
@@ -2134,18 +2185,22 @@ class LeaderLayer extends ContainerLayer {
21342185 ///
21352186 /// The [offset] property must be non-null before the compositing phase of the
21362187 /// pipeline.
2137- LeaderLayer ({ required LayerLink link, this . offset = Offset .zero }) : assert (link != null ), _link = link;
2188+ LeaderLayer ({ required LayerLink link, Offset offset = Offset .zero }) : assert (link != null ), _link = link, _offset = offset ;
21382189
21392190 /// The object with which this layer should register.
21402191 ///
21412192 /// The link will be established when this layer is [attach] ed, and will be
21422193 /// cleared when this layer is [detach] ed.
21432194 LayerLink get link => _link;
2195+ LayerLink _link;
21442196 set link (LayerLink value) {
21452197 assert (value != null );
2198+ if (_link == value) {
2199+ return ;
2200+ }
2201+ _link._leader = null ;
21462202 _link = value;
21472203 }
2148- LayerLink _link;
21492204
21502205 /// Offset from parent in the parent's coordinate system.
21512206 ///
@@ -2154,23 +2209,34 @@ class LeaderLayer extends ContainerLayer {
21542209 ///
21552210 /// The [offset] property must be non-null before the compositing phase of the
21562211 /// pipeline.
2157- Offset offset;
2212+ Offset get offset => _offset;
2213+ Offset _offset;
2214+ set offset (Offset value) {
2215+ assert (value != null );
2216+ if (value == _offset) {
2217+ return ;
2218+ }
2219+ _offset = value;
2220+ if (! alwaysNeedsAddToScene) {
2221+ markNeedsAddToScene ();
2222+ }
2223+ }
21582224
21592225 /// {@macro flutter.rendering.FollowerLayer.alwaysNeedsAddToScene}
21602226 @override
2161- bool get alwaysNeedsAddToScene => true ;
2227+ bool get alwaysNeedsAddToScene => _link._connectedFollowers > 0 ;
21622228
21632229 @override
21642230 void attach (Object owner) {
21652231 super .attach (owner);
2166- assert (link.leader == null );
2232+ assert (link._leader == null );
21672233 _lastOffset = null ;
21682234 link._leader = this ;
21692235 }
21702236
21712237 @override
21722238 void detach () {
2173- assert (link.leader == this );
2239+ assert (link._leader == this );
21742240 link._leader = null ;
21752241 _lastOffset = null ;
21762242 super .detach ();
@@ -2256,6 +2322,10 @@ class FollowerLayer extends ContainerLayer {
22562322 LayerLink get link => _link;
22572323 set link (LayerLink value) {
22582324 assert (value != null );
2325+ if (value != _link && _leaderHandle != null ) {
2326+ _leaderHandle! .dispose ();
2327+ _leaderHandle = value._registerFollower ();
2328+ }
22592329 _link = value;
22602330 }
22612331 LayerLink _link;
@@ -2302,6 +2372,21 @@ class FollowerLayer extends ContainerLayer {
23022372 /// * [unlinkedOffset] , for when the layer is not linked.
23032373 Offset ? linkedOffset;
23042374
2375+ _LayerLinkHandle ? _leaderHandle;
2376+
2377+ @override
2378+ void attach (Object owner) {
2379+ super .attach (owner);
2380+ _leaderHandle = _link._registerFollower ();
2381+ }
2382+
2383+ @override
2384+ void detach () {
2385+ super .detach ();
2386+ _leaderHandle? .dispose ();
2387+ _leaderHandle = null ;
2388+ }
2389+
23052390 Offset ? _lastOffset;
23062391 Matrix4 ? _lastTransform;
23072392 Matrix4 ? _invertedTransform;
@@ -2321,7 +2406,7 @@ class FollowerLayer extends ContainerLayer {
23212406
23222407 @override
23232408 bool findAnnotations <S extends Object >(AnnotationResult <S > result, Offset localPosition, { required bool onlyFirst }) {
2324- if (link .leader == null ) {
2409+ if (_leaderHandle ! .leader == null ) {
23252410 if (showWhenUnlinked! ) {
23262411 return super .findAnnotations (result, localPosition - unlinkedOffset! , onlyFirst: onlyFirst);
23272412 }
@@ -2400,7 +2485,7 @@ class FollowerLayer extends ContainerLayer {
24002485 void _establishTransform () {
24012486 assert (link != null );
24022487 _lastTransform = null ;
2403- final LeaderLayer ? leader = link .leader;
2488+ final LeaderLayer ? leader = _leaderHandle ! .leader;
24042489 // Check to see if we are linked.
24052490 if (leader == null )
24062491 return ;
@@ -2462,7 +2547,7 @@ class FollowerLayer extends ContainerLayer {
24622547 void addToScene (ui.SceneBuilder builder) {
24632548 assert (link != null );
24642549 assert (showWhenUnlinked != null );
2465- if (link .leader == null && ! showWhenUnlinked! ) {
2550+ if (_leaderHandle ! .leader == null && ! showWhenUnlinked! ) {
24662551 _lastTransform = null ;
24672552 _lastOffset = null ;
24682553 _inverseDirty = true ;
0 commit comments