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