|
15 | 15 | */
|
16 | 16 | package com.squareup.workflow.ui.compose.internal
|
17 | 17 |
|
18 |
| -import android.content.Context |
19 |
| -import android.view.ViewGroup.LayoutParams.MATCH_PARENT |
20 |
| -import android.widget.FrameLayout |
| 18 | +import android.view.View |
21 | 19 | import androidx.compose.Composable
|
| 20 | +import androidx.compose.onPreCommit |
| 21 | +import androidx.compose.remember |
| 22 | +import androidx.ui.core.ContextAmbient |
22 | 23 | import androidx.ui.core.Modifier
|
| 24 | +import androidx.ui.core.Ref |
23 | 25 | import androidx.ui.foundation.Box
|
| 26 | +import androidx.ui.viewinterop.AndroidView |
24 | 27 | import com.squareup.workflow.ui.ViewEnvironment
|
25 | 28 | import com.squareup.workflow.ui.ViewFactory
|
26 |
| -import com.squareup.workflow.ui.WorkflowViewStub |
| 29 | +import com.squareup.workflow.ui.canShowRendering |
27 | 30 | import com.squareup.workflow.ui.compose.ComposeViewFactory
|
28 |
| -import com.squareup.workflow.ui.compose.internal.ComposableViewStubWrapper.Update |
| 31 | +import com.squareup.workflow.ui.showRendering |
29 | 32 |
|
30 | 33 | /**
|
31 | 34 | * Renders [rendering] into the composition using the `ViewRegistry` from the [ViewEnvironment] to
|
@@ -53,46 +56,36 @@ import com.squareup.workflow.ui.compose.internal.ComposableViewStubWrapper.Updat
|
53 | 56 | // view system and can just invoke the binding's composable function directly.
|
54 | 57 | if (viewFactory is ComposeViewFactory) {
|
55 | 58 | viewFactory.showRenderingWrappedWithRoot(rendering, viewEnvironment)
|
56 |
| - } else { |
57 |
| - // Plumb the current composition "context" through the ViewEnvironment so any nested |
58 |
| - // composable factories get access to any ambients currently in effect. |
59 |
| - // See setOrContinueContent(). |
60 |
| - val newEnvironment = viewEnvironment.withParentComposition() |
| 59 | + return@Box |
| 60 | + } |
61 | 61 |
|
62 |
| - // IntelliJ currently complains very loudly about this function call, but it actually |
63 |
| - // compiles. The IDE tooling isn't currently able to recognize that the Compose compiler |
64 |
| - // accepts this code. |
65 |
| - ComposableViewStubWrapper(update = Update(rendering, newEnvironment, this)) |
| 62 | + val (childView, newEnvironment) = createChildView(viewFactory, rendering, viewEnvironment) |
| 63 | + onPreCommit(childView, newEnvironment, rendering) { |
| 64 | + childView.showRendering(rendering, newEnvironment) |
66 | 65 | }
|
| 66 | + AndroidView(childView) |
67 | 67 | }
|
68 | 68 | }
|
69 | 69 |
|
70 |
| -/** |
71 |
| - * Wraps a [WorkflowViewStub] with an API that is more Compose-friendly. |
72 |
| - * |
73 |
| - * In particular, Compose will only generate `Emittable`s for views with a single constructor |
74 |
| - * that takes a [Context]. |
75 |
| - * |
76 |
| - * See [this slack message](https://kotlinlang.slack.com/archives/CJLTWPH7S/p1576264533012000?thread_ts=1576262311.008800&cid=CJLTWPH7S). |
77 |
| - */ |
78 |
| -private class ComposableViewStubWrapper(context: Context) : FrameLayout(context) { |
79 |
| - |
80 |
| - data class Update( |
81 |
| - val rendering: Any, |
82 |
| - val viewEnvironment: ViewEnvironment, |
83 |
| - val viewFactory: ViewFactory<Any> |
84 |
| - ) |
85 |
| - |
86 |
| - private val viewStub = ForkedViewStub(context) |
87 |
| - |
88 |
| - init { |
89 |
| - addView(viewStub) |
90 |
| - } |
91 |
| - |
92 |
| - // Compose turns this into a parameter when you invoke this class as a Composable. |
93 |
| - fun setUpdate(update: Update) { |
94 |
| - viewStub.update(update.rendering, update.viewEnvironment, update.viewFactory) |
95 |
| - } |
| 70 | +@Composable private fun <R : Any> createChildView( |
| 71 | + viewFactory: ViewFactory<R>, |
| 72 | + rendering: R, |
| 73 | + viewEnvironment: ViewEnvironment |
| 74 | +): Pair<View, ViewEnvironment> { |
| 75 | + val childView = remember { Ref<View>() } |
| 76 | + val newEnvironment = if (childView.value?.canShowRendering(rendering) != true) { |
| 77 | + // Plumb the current composition "context" through the ViewEnvironment so any nested |
| 78 | + // composable factories get access to any ambients currently in effect. |
| 79 | + // See setOrContinueContent(). |
| 80 | + viewEnvironment.withParentComposition() |
| 81 | + .also { newEnvironment -> |
| 82 | + childView.value = viewFactory.buildView( |
| 83 | + initialRendering = rendering, |
| 84 | + initialViewEnvironment = newEnvironment, |
| 85 | + contextForNewView = ContextAmbient.current |
| 86 | + ) |
| 87 | + } |
| 88 | + } else viewEnvironment |
96 | 89 |
|
97 |
| - override fun getLayoutParams(): LayoutParams = LayoutParams(MATCH_PARENT, MATCH_PARENT) |
| 90 | + return Pair(childView.value!!, newEnvironment) |
98 | 91 | }
|
0 commit comments