Add animated chain demo
Added demo that takes advantage of the improved handling of
ConstraintSet with `animateChanges = true`.
Bug: n/a
Test: n/a
Change-Id: Iad16fb96994db8e3d640e2d6a19d010add07a0fc
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt b/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt
new file mode 100644
index 0000000..20dacf6
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/AllDemos.kt
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.constraintlayout.compose.demos
+
+import androidx.compose.foundation.background
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.height
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.shape.RoundedCornerShape
+import androidx.compose.material.Icon
+import androidx.compose.material.MaterialTheme
+import androidx.compose.material.Text
+import androidx.compose.material.icons.Icons
+import androidx.compose.material.icons.filled.ArrowBack
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.draw.clip
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.graphicsLayer
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.compose.ui.unit.sp
+
+data class ComposeDemo(val title: String, val content: @Composable () -> Unit)
+
+val AllComposeConstraintLayoutDemos: List<ComposeDemo> =
+ listOf(
+ ComposeDemo("CustomColorInKeyAttributes") { CustomColorInKeyAttributesDemo() },
+ ComposeDemo("SimpleOnSwipe") { SimpleOnSwipe() },
+ ComposeDemo("AnimatedChainOrientation") { ChainsAnimatedOrientationDemo() }
+ )
+
+/**
+ * Main screen to explore and interact with all demos from [AllComposeConstraintLayoutDemos].
+ */
+@Preview
+@Composable
+fun ComposeConstraintLayoutDemos() {
+ var displayedDemo by remember { mutableStateOf<ComposeDemo?>(null) }
+ Column {
+ Column {
+ displayedDemo?.let {
+ // Header with back button
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .height(50.dp)
+ .background(Color.White)
+ .graphicsLayer(shadowElevation = 2f)
+ .clickable { displayedDemo = null }, // Return to list of demos
+ verticalAlignment = Alignment.CenterVertically
+ ) {
+ Icon(imageVector = Icons.Default.ArrowBack, contentDescription = "Back")
+ Text(text = it.title)
+ }
+ } ?: kotlin.run {
+ // Main Title
+ Text(text = "ComposeConstraintLayoutDemos", style = MaterialTheme.typography.h6)
+ Spacer(modifier = Modifier.height(8.dp))
+ }
+ }
+ Column(verticalArrangement = Arrangement.spacedBy(8.dp)) {
+ displayedDemo?.let { demo ->
+ // Display selected demo
+ Box(
+ Modifier
+ .fillMaxWidth()
+ .weight(1.0f, true)
+ ) {
+ demo.content()
+ }
+ } ?: kotlin.run {
+ // Display list of demos
+ AllComposeConstraintLayoutDemos.forEach {
+ ComposeDemoItem(it.title) { displayedDemo = it }
+ }
+ }
+ }
+ }
+}
+
+@Composable
+private fun ComposeDemoItem(title: String, modifier: Modifier = Modifier, onClick: () -> Unit) {
+ Box(
+ modifier = modifier
+ .padding(horizontal = 8.dp)
+ .fillMaxWidth()
+ .height(44.dp)
+ .clip(RoundedCornerShape(10.dp))
+ .background(Color.White)
+ .clickable(onClick = onClick)
+ .padding(start = 8.dp),
+ contentAlignment = Alignment.CenterStart
+ ) {
+ Text(
+ text = title,
+ modifier = Modifier,
+ fontSize = 16.sp
+ )
+ }
+}
\ No newline at end of file
diff --git a/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/ChainsDemo.kt b/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/ChainsDemo.kt
new file mode 100644
index 0000000..5611bc4
--- /dev/null
+++ b/constraintlayout/constraintlayout-compose/integration-tests/constraintlayout-compose-demos/src/main/java/androidx/constraintlayout/compose/demos/ChainsDemo.kt
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package androidx.constraintlayout.compose.demos
+
+import androidx.compose.animation.core.tween
+import androidx.compose.foundation.background
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.Column
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.material.Button
+import androidx.compose.material.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.layout.layoutId
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.unit.dp
+import androidx.constraintlayout.compose.ConstraintLayout
+import androidx.constraintlayout.compose.ConstraintSet
+import androidx.constraintlayout.compose.Dimension
+
+@Preview
+@Composable
+fun ChainsAnimatedOrientationDemo() {
+ val boxColors = listOf(Color.Red, Color.Blue, Color.Green)
+ var isHorizontal by remember { mutableStateOf(true) }
+
+ Column(Modifier.fillMaxSize()) {
+ ConstraintLayout(
+ constraintSet = ConstraintSet {
+ val (box0, box1, box2) = createRefsFor("box0", "box1", "box2")
+ box1.withChainParams(8.dp, 8.dp, 8.dp, 8.dp)
+
+ if (isHorizontal) {
+ constrain(box0, box1, box2) {
+ width = Dimension.fillToConstraints
+ height = Dimension.value(20.dp)
+ centerVerticallyTo(parent)
+ }
+ constrain(box1) {
+ // Override height to be a ratio
+ height = Dimension.ratio("2:1")
+ }
+
+ createHorizontalChain(box0, box1, box2)
+ } else {
+ constrain(box0, box1, box2) {
+ width = Dimension.value(20.dp)
+ height = Dimension.fillToConstraints
+ centerHorizontallyTo(parent)
+ }
+ constrain(box1) {
+ // Override width to be a ratio
+ width = Dimension.ratio("2:1")
+ }
+
+ createVerticalChain(box0, box1, box2)
+ }
+ },
+ animateChanges = true,
+ animationSpec = tween(800),
+ modifier = Modifier
+ .fillMaxWidth()
+ .weight(1.0f, true)
+ ) {
+ boxColors.forEachIndexed { index, color ->
+ Box(
+ modifier = Modifier
+ .layoutId("box$index")
+ .background(color)
+ )
+ }
+ }
+ Button(onClick = { isHorizontal = !isHorizontal }) {
+ Text(text = "Toggle Orientation")
+ }
+ }
+}
\ No newline at end of file