[go: nahoru, domu]

Add attach() callback to LayoutNodeWrapper

The LayoutNodeWrapper class has a detach() callback. Add an attach() callback too. This is needed by FocusModifier and KeyInputModifier so that they can keep track of children (add/remove children) using attach and detach.

Fixes: 154962853
Test: Ran demo app locally
Change-Id: I049251f782b5c48eb207309af8705ffd69cb1c94
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
index ff2fa34..7792faa 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/ComponentNodes.kt
@@ -765,6 +765,7 @@
             if (oldPlaceable != layoutNodeWrapper) {
                 oldPlaceable.detach()
                 requestRemeasure()
+                layoutNodeWrapper.attach()
             } else if (!needsRemeasure && !needsRelayout && addedCallback) {
                 // We need to notify the callbacks of a change in position since there's
                 // a new one.
@@ -795,6 +796,7 @@
         requestRemeasure()
         parentDataDirty = true
         parentLayoutNode?.layoutChildrenDirty = true
+        layoutNodeWrapper.attach()
         onAttach?.invoke(owner)
     }
 
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt b/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
index 1f449b1..80d4b9b 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/DelegatingLayoutNodeWrapper.kt
@@ -128,6 +128,11 @@
         wrapped.maxIntrinsicHeight(width, layoutDirection)
     override val parentData: Any? get() = wrapped.parentData
 
+    override fun attach() {
+        wrapped.attach()
+        _isAttached = true
+    }
+
     override fun detach() {
         _isAttached = false
         wrapped.detach()
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt b/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
index 9b9d1b9..db54e55 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/InnerPlaceable.kt
@@ -148,6 +148,10 @@
         }
     }
 
+    override fun attach() {
+        // Do nothing. InnerPlaceable only is attached when the LayoutNode is attached.
+    }
+
     override fun detach() {
         // Do nothing. InnerPlaceable only is detached when the LayoutNode is detached.
     }
diff --git a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
index 5c18498..a3eb00d 100644
--- a/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
+++ b/ui/ui-platform/src/main/java/androidx/ui/core/LayoutNodeWrapper.kt
@@ -218,9 +218,26 @@
     }
 
     /**
-     * Detaches the LayoutNodeWrapper and its wrapped LayoutNodeWrapper from an active LayoutNode.
-     * This will be called whenever the modifier chain is replaced and the LayoutNodeWrappers
-     * are recreated.
+     * Attaches the [LayoutNodeWrapper] and its wrapped [LayoutNodeWrapper] to an active
+     * LayoutNode.
+     *
+     * This will be called when the [LayoutNode] associated with this [LayoutNodeWrapper] is
+     * attached to the [Owner].
+     *
+     * It is also called whenever the modifier chain is replaced and the [LayoutNodeWrapper]s are
+     * recreated.
+     */
+    abstract fun attach()
+
+    /**
+     * Detaches the [LayoutNodeWrapper] and its wrapped [LayoutNodeWrapper] from an active
+     * LayoutNode.
+     *
+     * This will be called when the [LayoutNode] associated with this [LayoutNodeWrapper] is
+     * detached from the [Owner].
+     *
+     * It is also called whenever the modifier chain is replaced and the [LayoutNodeWrapper]s are
+     * recreated.
      */
     abstract fun detach()
 
diff --git a/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt b/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
index e2d0980..5750760 100644
--- a/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
+++ b/ui/ui-platform/src/test/java/androidx/ui/core/ComponentNodeTest.kt
@@ -19,7 +19,6 @@
 import androidx.ui.core.pointerinput.PointerInputFilter
 import androidx.ui.core.pointerinput.PointerInputModifier
 import androidx.ui.core.pointerinput.resize
-import androidx.ui.unit.IntPx
 import androidx.ui.unit.IntPxPosition
 import androidx.ui.unit.PxPosition
 import androidx.ui.unit.ipx
@@ -765,20 +764,23 @@
         assertFalse(layoutNode.coordinates.isAttached)
     }
 
-    // The LayoutNodeWrapper should be detached when it has been replaced
+    // The LayoutNodeWrapper should be detached when it has been replaced.
     @Test
     fun layoutNodeWrapperAttachedWhenLayoutNodeAttached() {
         val layoutNode = LayoutNode()
         val drawModifier = Modifier.drawBehind { }
+
         layoutNode.modifier = drawModifier
-        val layoutNodeWrapper = layoutNode.layoutNodeWrapper
-        assertFalse(layoutNodeWrapper.isAttached)
+        val oldLayoutNodeWrapper = layoutNode.layoutNodeWrapper
+        assertFalse(oldLayoutNodeWrapper.isAttached)
+
         layoutNode.attach(mockOwner())
-        assertTrue(layoutNodeWrapper.isAttached)
+        assertTrue(oldLayoutNodeWrapper.isAttached)
+
         layoutNode.modifier = Modifier.drawBehind { }
-        assertFalse(layoutNodeWrapper.isAttached)
-        assertTrue(layoutNode.coordinates.isAttached)
-        assertTrue(layoutNode.coordinates.isAttached)
+        val newLayoutNodeWrapper = layoutNode.layoutNodeWrapper
+        assertTrue(newLayoutNodeWrapper.isAttached)
+        assertFalse(oldLayoutNodeWrapper.isAttached)
     }
 
     @Test