1 /*
<lambda>null2 * Copyright 2023 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 @file:Suppress("DEPRECATION")
18
19 package androidx.compose.foundation.layout.samples
20
21 import androidx.annotation.Sampled
22 import androidx.compose.foundation.BorderStroke
23 import androidx.compose.foundation.background
24 import androidx.compose.foundation.border
25 import androidx.compose.foundation.horizontalScroll
26 import androidx.compose.foundation.layout.Arrangement
27 import androidx.compose.foundation.layout.Box
28 import androidx.compose.foundation.layout.ExperimentalLayoutApi
29 import androidx.compose.foundation.layout.FlowColumn
30 import androidx.compose.foundation.layout.FlowColumnOverflow
31 import androidx.compose.foundation.layout.FlowColumnOverflowScope
32 import androidx.compose.foundation.layout.fillMaxWidth
33 import androidx.compose.foundation.layout.height
34 import androidx.compose.foundation.layout.padding
35 import androidx.compose.foundation.layout.width
36 import androidx.compose.foundation.layout.wrapContentHeight
37 import androidx.compose.foundation.layout.wrapContentWidth
38 import androidx.compose.foundation.rememberScrollState
39 import androidx.compose.material.Text
40 import androidx.compose.runtime.Composable
41 import androidx.compose.runtime.getValue
42 import androidx.compose.runtime.mutableStateOf
43 import androidx.compose.runtime.remember
44 import androidx.compose.runtime.setValue
45 import androidx.compose.ui.Alignment
46 import androidx.compose.ui.Modifier
47 import androidx.compose.ui.graphics.Color
48 import androidx.compose.ui.text.font.FontWeight
49 import androidx.compose.ui.unit.dp
50 import androidx.compose.ui.unit.sp
51
52 @OptIn(ExperimentalLayoutApi::class)
53 @Sampled
54 @Composable
55 fun SimpleFlowColumn() {
56
57 Text(
58 modifier =
59 Modifier.fillMaxWidth(1f).padding(20.dp).wrapContentHeight(align = Alignment.Top),
60 text = "FlowColumn with weights",
61 fontWeight = FontWeight.Bold
62 )
63
64 FlowColumn(
65 Modifier.padding(20.dp)
66 .fillMaxWidth()
67 .padding(20.dp)
68 .wrapContentHeight(align = Alignment.Top)
69 .height(200.dp)
70 .border(BorderStroke(2.dp, Color.Gray)),
71 horizontalArrangement = Arrangement.spacedBy(10.dp),
72 verticalArrangement = Arrangement.spacedBy(20.dp),
73 maxItemsInEachColumn = 3,
74 ) {
75 repeat(17) { index ->
76 Box(
77 Modifier.align(Alignment.CenterHorizontally)
78 .width(50.dp)
79 .height(50.dp)
80 .weight(1f, true)
81 .background(color = Color.Green)
82 ) {
83 Text(text = index.toString(), fontSize = 18.sp, modifier = Modifier.padding(3.dp))
84 }
85 }
86 }
87 }
88
89 @OptIn(ExperimentalLayoutApi::class)
90 @Sampled
91 @Composable
SimpleFlowColumnMaxLinesWithSeeMorenull92 fun SimpleFlowColumnMaxLinesWithSeeMore() {
93 val totalCount = 20
94 var maxLines by remember { mutableStateOf(2) }
95
96 Text(
97 modifier =
98 Modifier.fillMaxWidth(1f).padding(20.dp).wrapContentHeight(align = Alignment.Top),
99 text = "Flow Column with Max Lines and See More",
100 fontWeight = FontWeight.Bold
101 )
102
103 FlowColumn(
104 modifier =
105 Modifier.height(200.dp)
106 .horizontalScroll(rememberScrollState())
107 .padding(20.dp)
108 .wrapContentWidth(align = Alignment.Start),
109 verticalArrangement = Arrangement.spacedBy(10.dp),
110 horizontalArrangement = Arrangement.spacedBy(20.dp),
111 maxLines = maxLines,
112 overflow = FlowColumnOverflow.expandIndicator { Ellipsis(text = "...") { maxLines += 2 } }
113 ) {
114 repeat(totalCount) {
115 Box(
116 modifier =
117 Modifier.align(Alignment.CenterHorizontally)
118 .height(50.dp)
119 .width(50.dp)
120 .background(Color.Green)
121 ) {
122 Text(
123 text = it.toString(),
124 fontSize = 18.sp,
125 modifier = Modifier.padding(3.dp).align(Alignment.Center)
126 )
127 }
128 }
129 }
130 }
131
132 @OptIn(ExperimentalLayoutApi::class)
133 @Composable
SimpleFlowColumnWithMaxWidthnull134 fun SimpleFlowColumnWithMaxWidth() {
135 var initialWidth = 200.dp // Reversed from initialHeight
136 var width by remember { mutableStateOf(initialWidth) } // Reversed from height
137
138 Text(
139 modifier =
140 Modifier.fillMaxWidth(1f).padding(20.dp).wrapContentHeight(align = Alignment.Top),
141 text = "FlowColumn with MaxWidth and See More or collapse",
142 fontWeight = FontWeight.Bold
143 )
144
145 FlowColumn(
146 modifier =
147 Modifier.height(200.dp)
148 .padding(20.dp)
149 .horizontalScroll(rememberScrollState())
150 .width(width)
151 .wrapContentWidth(align = Alignment.Start),
152 verticalArrangement = Arrangement.spacedBy(10.dp),
153 horizontalArrangement = Arrangement.spacedBy(20.dp),
154 overflow =
155 FlowColumnOverflow.expandOrCollapseIndicator(
156 minWidthToShowCollapse = 200.dp,
157 expandIndicator = { Ellipsis(text = "...") { width += 200.dp } },
158 collapseIndicator = { Ellipsis(text = "<") { width = 100.dp } }
159 )
160 ) {
161 repeat(40) {
162 Box(
163 modifier =
164 Modifier.align(Alignment.CenterHorizontally)
165 .height(50.dp)
166 .width(50.dp)
167 .background(Color.Green)
168 ) {
169 Text(text = it.toString(), fontSize = 18.sp, modifier = Modifier.padding(3.dp))
170 }
171 }
172 }
173 }
174
175 @OptIn(ExperimentalLayoutApi::class)
176 @Sampled
177 @Composable
SimpleFlowColumnMaxLinesDynamicSeeMorenull178 fun SimpleFlowColumnMaxLinesDynamicSeeMore() {
179 val totalCount = 20
180 var maxLines by remember { mutableStateOf(2) }
181
182 Text(
183 modifier =
184 Modifier.fillMaxWidth(1f).padding(20.dp).wrapContentHeight(align = Alignment.Top),
185 text = "FlowColumn with MaxLines and +N button",
186 fontWeight = FontWeight.Bold
187 )
188 val moreOrCollapseIndicator =
189 @Composable { scope: FlowColumnOverflowScope ->
190 DynamicSeeMoreForDrawText(
191 isHorizontal = false,
192 totalCount = totalCount,
193 { scope.shownItemCount },
194 onExpand = { maxLines += 2 },
195 onShrink = { maxLines = 2 }
196 )
197 }
198 FlowColumn(
199 modifier =
200 Modifier.height(200.dp)
201 .padding(20.dp)
202 .horizontalScroll(rememberScrollState())
203 .wrapContentWidth(align = Alignment.Start),
204 verticalArrangement = Arrangement.spacedBy(10.dp),
205 horizontalArrangement = Arrangement.spacedBy(20.dp),
206 maxLines = maxLines,
207 overflow =
208 FlowColumnOverflow.expandOrCollapseIndicator(
209 minColumnsToShowCollapse = 4,
210 expandIndicator = moreOrCollapseIndicator,
211 collapseIndicator = moreOrCollapseIndicator
212 )
213 ) {
214 repeat(totalCount) {
215 Box(
216 modifier =
217 Modifier.align(Alignment.CenterHorizontally)
218 .height(50.dp)
219 .width(50.dp)
220 .background(Color.Green)
221 ) {
222 Text(
223 text = it.toString(),
224 fontSize = 18.sp,
225 modifier = Modifier.padding(3.dp).align(Alignment.Center)
226 )
227 }
228 }
229 }
230 }
231
232 @OptIn(ExperimentalLayoutApi::class)
233 @Sampled
234 @Composable
SimpleFlowColumn_EqualWidthnull235 fun SimpleFlowColumn_EqualWidth() {
236 FlowColumn(
237 Modifier.padding(20.dp)
238 .wrapContentHeight(align = Alignment.Top)
239 .wrapContentWidth(align = Alignment.Start),
240 horizontalArrangement = Arrangement.spacedBy(10.dp),
241 verticalArrangement = Arrangement.spacedBy(20.dp),
242 maxItemsInEachColumn = 3,
243 ) {
244 repeat(9) {
245 Box(Modifier.height(100.dp).fillMaxColumnWidth(1f).background(Color.Green)) {
246 val text = generateRandomString(IntRange(1, 5).random())
247 Text(text = text, fontSize = 18.sp, modifier = Modifier.padding(3.dp))
248 }
249 }
250 }
251 }
252