1 /*
<lambda>null2 * Copyright 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package androidx.constraintlayout.compose.demos
18
19 import androidx.compose.animation.core.tween
20 import androidx.compose.foundation.background
21 import androidx.compose.foundation.layout.Box
22 import androidx.compose.foundation.layout.Column
23 import androidx.compose.foundation.layout.fillMaxSize
24 import androidx.compose.foundation.layout.fillMaxWidth
25 import androidx.compose.material.Button
26 import androidx.compose.material.Text
27 import androidx.compose.runtime.Composable
28 import androidx.compose.runtime.getValue
29 import androidx.compose.runtime.mutableStateOf
30 import androidx.compose.runtime.remember
31 import androidx.compose.runtime.setValue
32 import androidx.compose.ui.Modifier
33 import androidx.compose.ui.graphics.Color
34 import androidx.compose.ui.layout.layoutId
35 import androidx.compose.ui.tooling.preview.Preview
36 import androidx.compose.ui.unit.dp
37 import androidx.constraintlayout.compose.ConstraintLayout
38 import androidx.constraintlayout.compose.ConstraintLayoutBaseScope
39 import androidx.constraintlayout.compose.ConstraintSet
40 import androidx.constraintlayout.compose.ConstraintSetScope
41 import androidx.constraintlayout.compose.Dimension
42
43 /**
44 * Shows the usage of `animateChanges = true` with a chain that changes orientation.
45 *
46 * Also shown here, usage of [ConstraintLayoutBaseScope.withChainParams], [Dimension.ratio] and
47 * [ConstraintSetScope.createRefsFor].
48 */
49 @Preview
50 @Composable
51 fun ChainsAnimatedOrientationDemo() {
52 val boxColors = listOf(Color.Red, Color.Blue, Color.Green)
53 var isHorizontal by remember { mutableStateOf(true) }
54
55 Column(Modifier.fillMaxSize()) {
56 ConstraintLayout(
57 constraintSet =
58 ConstraintSet {
59 // Create multiple references using destructuring declaration
60 val (box0, box1, box2) = createRefsFor("box0", "box1", "box2")
61
62 // Assign Chain element margins with `withChainParams`
63 box1.withChainParams(8.dp, 8.dp, 8.dp, 8.dp)
64
65 // When State value of `isHorizontal` changes, ConstraintLayout will
66 // automatically
67 // animate ot the resulting ConstraintSet
68 if (isHorizontal) {
69 constrain(box0, box1, box2) {
70 width = Dimension.fillToConstraints
71 height = Dimension.value(20.dp)
72 centerVerticallyTo(parent)
73 }
74 constrain(box1) {
75 // Override height to be a ratio
76 height = Dimension.ratio("2:1")
77 }
78
79 createHorizontalChain(box0, box1, box2)
80 } else {
81 constrain(box0, box1, box2) {
82 width = Dimension.value(20.dp)
83 height = Dimension.fillToConstraints
84 centerHorizontallyTo(parent)
85 }
86 constrain(box1) {
87 // Override width to be a ratio
88 width = Dimension.ratio("2:1")
89 }
90
91 createVerticalChain(box0, box1, box2)
92 }
93 },
94 modifier = Modifier.fillMaxWidth().weight(1.0f, true),
95 animateChangesSpec = tween(800),
96 ) {
97 boxColors.forEachIndexed { index, color ->
98 Box(modifier = Modifier.layoutId("box$index").background(color))
99 }
100 }
101 Button(onClick = { isHorizontal = !isHorizontal }) { Text(text = "Toggle Orientation") }
102 }
103 }
104
105 @Preview
106 @Composable
ChainsAnimatedOrientationDemo1null107 fun ChainsAnimatedOrientationDemo1() {
108 val boxColors = listOf(Color.Red, Color.Blue, Color.Green)
109 var isHorizontal by remember { mutableStateOf(true) }
110
111 Column(Modifier.fillMaxSize()) {
112 ConstraintLayout(
113 modifier = Modifier.fillMaxWidth().weight(1.0f, true),
114 animateChangesSpec = tween(800)
115 ) {
116 val (box0, box1, box2) = createRefs()
117 if (isHorizontal) {
118 createHorizontalChain(box0, box1.withChainParams(8.dp, 8.dp, 8.dp, 8.dp), box2)
119 } else {
120 createVerticalChain(box0, box1.withChainParams(8.dp, 8.dp, 8.dp, 8.dp), box2)
121 }
122 Box(
123 modifier =
124 Modifier.constrainAs(box0) {
125 if (isHorizontal) {
126 width = Dimension.fillToConstraints
127 height = Dimension.value(20.dp)
128 centerVerticallyTo(parent)
129 } else {
130 width = Dimension.value(20.dp)
131 height = Dimension.fillToConstraints
132 centerHorizontallyTo(parent)
133 }
134 }
135 .background(boxColors[0])
136 )
137 Box(
138 modifier =
139 Modifier.constrainAs(box1) {
140 if (isHorizontal) {
141 width = Dimension.fillToConstraints
142 height = Dimension.ratio("2:1")
143 centerVerticallyTo(parent)
144 } else {
145 width = Dimension.ratio("2:1")
146 height = Dimension.fillToConstraints
147 centerHorizontallyTo(parent)
148 }
149 }
150 .background(boxColors[1])
151 )
152 Box(
153 modifier =
154 Modifier.constrainAs(box2) {
155 if (isHorizontal) {
156 width = Dimension.fillToConstraints
157 height = Dimension.value(20.dp)
158 centerVerticallyTo(parent)
159 } else {
160 width = Dimension.value(20.dp)
161 height = Dimension.fillToConstraints
162 centerHorizontallyTo(parent)
163 }
164 }
165 .background(boxColors[2])
166 )
167 }
168 Button(onClick = { isHorizontal = !isHorizontal }) { Text(text = "Toggle Orientation") }
169 }
170 }
171