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