Merge "Removes Appcompat and Fragment dependencies from compose:ui:ui" into androidx-main am: d192917993
Original change: https://android-review.googlesource.com/c/platform/frameworks/support/+/1603516
MUST ONLY BE SUBMITTED BY AUTOMERGER
Change-Id: I4a00eb72e7acae366c39bebacdb7740372aedc9f
diff --git a/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt b/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
index 9516dd8..3e09abe 100644
--- a/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
+++ b/activity/activity-compose/src/main/java/androidx/activity/compose/ComponentActivity.kt
@@ -21,12 +21,16 @@
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionContext
import androidx.compose.ui.platform.ComposeView
+import androidx.lifecycle.ViewTreeLifecycleOwner
+import androidx.lifecycle.ViewTreeViewModelStoreOwner
+import androidx.savedstate.ViewTreeSavedStateRegistryOwner
/**
* Composes the given composable into the given activity. The [content] will become the root view
* of the given activity.
*
- * This is roughly equivalent to calling [setContentView] with a [ComposeView] i.e.:
+ * This is roughly equivalent to calling [ComponentActivity.setContentView] with a [ComposeView]
+ * i.e.:
*
* ```
* setContentView(
@@ -57,6 +61,9 @@
// to have ComposeView create the composition on attach
setParentCompositionContext(parent)
setContent(content)
+ // Set the view tree owners before setting the content view so that the inflation process
+ // and attach listeners will see them already present
+ setOwners()
setContentView(this, DefaultActivityContentLayoutParams)
}
}
@@ -65,3 +72,20 @@
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
+
+/**
+ * These owners are not set before AppCompat 1.3+ due to a bug, so we need to set them manually in
+ * case developers are using an older version of AppCompat.
+ */
+private fun ComponentActivity.setOwners() {
+ val decorView = window.decorView
+ if (ViewTreeLifecycleOwner.get(decorView) == null) {
+ ViewTreeLifecycleOwner.set(decorView, this)
+ }
+ if (ViewTreeViewModelStoreOwner.get(decorView) == null) {
+ ViewTreeViewModelStoreOwner.set(decorView, this)
+ }
+ if (ViewTreeSavedStateRegistryOwner.get(decorView) == null) {
+ ViewTreeSavedStateRegistryOwner.set(decorView, this)
+ }
+}
diff --git a/compose/material/material-icons-extended/build.gradle b/compose/material/material-icons-extended/build.gradle
index d1d0196..8808af5 100644
--- a/compose/material/material-icons-extended/build.gradle
+++ b/compose/material/material-icons-extended/build.gradle
@@ -56,6 +56,7 @@
androidTestImplementation(project(":test-screenshot"))
androidTestImplementation(project(":compose:ui:ui-test-junit4"))
androidTestImplementation(project(":activity:activity-compose"))
+ androidTestImplementation("androidx.appcompat:appcompat:1.3.0-beta01")
}
}
@@ -81,6 +82,7 @@
implementation(project(":test-screenshot"))
implementation(project(":compose:ui:ui-test-junit4"))
implementation(project(":activity:activity-compose"))
+ implementation("androidx.appcompat:appcompat:1.3.0-beta01")
implementation(ANDROIDX_TEST_RULES)
implementation(ANDROIDX_TEST_RUNNER)
diff --git a/compose/ui/ui/build.gradle b/compose/ui/ui/build.gradle
index 996054c..a4de7229 100644
--- a/compose/ui/ui/build.gradle
+++ b/compose/ui/ui/build.gradle
@@ -62,12 +62,9 @@
implementation("androidx.autofill:autofill:1.0.0")
implementation(KOTLIN_COROUTINES_ANDROID)
- // we don't use these dependencies but we need to ensure at least these versions are
- // used if the user adds these dependencies as otherwise AppCompatActivity and Fragment
- // will not propagate ViewTree*Owners we are relying on and we will crash.
- // TODO: remove these dependencies at some point: b/161814404
- implementation("androidx.fragment:fragment:1.3.0")
- implementation("androidx.appcompat:appcompat:1.3.0-beta01")
+ implementation("androidx.savedstate:savedstate:1.1.0")
+ implementation("androidx.lifecycle:lifecycle-runtime:2.3.0")
+ implementation("androidx.lifecycle:lifecycle-viewmodel:2.3.0")
testImplementation(ANDROIDX_TEST_RULES)
testImplementation(ANDROIDX_TEST_RUNNER)
@@ -82,8 +79,6 @@
testImplementation(project(":compose:ui:ui-test-junit4"))
testImplementation(project(":compose:test-utils"))
- androidTestImplementation("androidx.fragment:fragment:1.3.0")
- androidTestImplementation("androidx.appcompat:appcompat:1.1.0")
androidTestImplementation(ANDROIDX_TEST_UIAUTOMATOR)
androidTestImplementation(ANDROIDX_TEST_RULES)
androidTestImplementation(ANDROIDX_TEST_RUNNER)
@@ -108,6 +103,8 @@
androidTestImplementation("androidx.recyclerview:recyclerview:1.1.0")
androidTestImplementation("androidx.core:core-ktx:1.1.0")
androidTestImplementation(project(":activity:activity-compose"))
+ androidTestImplementation("androidx.appcompat:appcompat:1.3.0-beta01")
+ androidTestImplementation("androidx.fragment:fragment:1.3.0")
lintChecks(project(":compose:ui:ui-lint"))
lintPublish(project(":compose:ui:ui-lint"))
@@ -151,12 +148,9 @@
implementation("androidx.autofill:autofill:1.0.0")
implementation(KOTLIN_COROUTINES_ANDROID)
- // we don't use these dependencies but we need to ensure at least these versions are
- // used if the user adds these dependencies as otherwise AppCompatActivity and Fragment
- // will not propagate ViewTree*Owners we are relying on and we will crash.
- // TODO: remove these dependencies at some point: b/161814404
- implementation("androidx.fragment:fragment:1.3.0")
- implementation("androidx.appcompat:appcompat:1.3.0-beta01")
+ implementation("androidx.savedstate:savedstate:1.1.0")
+ implementation("androidx.lifecycle:lifecycle-runtime:2.3.0")
+ implementation("androidx.lifecycle:lifecycle-viewmodel:2.3.0")
}
jvmMain.dependencies {
@@ -188,7 +182,7 @@
androidAndroidTest.dependencies {
implementation("androidx.fragment:fragment:1.3.0")
- implementation("androidx.appcompat:appcompat:1.1.0")
+ implementation("androidx.appcompat:appcompat:1.3.0-beta01")
implementation(ANDROIDX_TEST_UIAUTOMATOR)
implementation(ANDROIDX_TEST_RULES)
implementation(ANDROIDX_TEST_RUNNER)
diff --git a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
index a88c480..a2c74d0 100644
--- a/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
+++ b/compose/ui/ui/src/androidMain/kotlin/androidx/compose/ui/platform/ComposeView.android.kt
@@ -29,6 +29,7 @@
import androidx.compose.ui.node.Owner
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.ViewTreeLifecycleOwner
+import androidx.savedstate.ViewTreeSavedStateRegistryOwner
/**
* Base class for custom [android.view.View]s implemented using Jetpack Compose UI.
@@ -203,6 +204,20 @@
override fun onAttachedToWindow() {
super.onAttachedToWindow()
+ val message = "If you are adding this ComposeView to an AppCompatActivity, make sure you " +
+ "are using AppCompat version 1.3+. If you are adding this ComposeView to a " +
+ "Fragment, make sure you are using Fragment version 1.3+. For other cases, manually " +
+ "set owners on this view by using `ViewTreeLifecycleOwner.set()` and " +
+ "`ViewTreeSavedStateRegistryOwner.set()`."
+ checkNotNull(ViewTreeLifecycleOwner.get(this)) {
+ "ViewTreeLifecycleOwner not set for this ComposeView. $message"
+ }
+ checkNotNull(ViewTreeSavedStateRegistryOwner.get(this)) {
+ "ViewTreeSavedStateRegistryOwner not set for this ComposeView. $message"
+ }
+ // Not checking for ViewTreeViewModelStoreOwner as we don't need it inside Compose, but we
+ // provide it in ComponentActivity.setContent for convenience.
+
if (shouldCreateCompositionOnAttachedToWindow) {
ensureCompositionCreated()
}
diff --git a/lifecycle/lifecycle-viewmodel-compose/build.gradle b/lifecycle/lifecycle-viewmodel-compose/build.gradle
index f914120..f546dff 100644
--- a/lifecycle/lifecycle-viewmodel-compose/build.gradle
+++ b/lifecycle/lifecycle-viewmodel-compose/build.gradle
@@ -44,7 +44,7 @@
androidTestImplementation(JUNIT)
androidTestImplementation(TRUTH)
androidTestImplementation "androidx.fragment:fragment:1.3.0"
- androidTestImplementation "androidx.appcompat:appcompat:1.1.0"
+ androidTestImplementation "androidx.appcompat:appcompat:1.3.0-beta01"
androidTestImplementation projectOrArtifact(":activity:activity-compose")
}