Skip to content

Commit 0c9024b

Browse files
authored
Add Material Carousel (#363)
* Add Carousel * Apply Spotless * add to components * Apply Spotless * Clean up landing screens, using Scaffold and list items. * Apply Spotless * Review comments --------- Co-authored-by: riggaroo <[email protected]>
1 parent d1e297b commit 0c9024b

File tree

5 files changed

+195
-53
lines changed

5 files changed

+195
-53
lines changed

compose/snippets/src/main/java/com/example/compose/snippets/SnippetsActivity.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import com.example.compose.snippets.components.AppBarExamples
3333
import com.example.compose.snippets.components.BadgeExamples
3434
import com.example.compose.snippets.components.ButtonExamples
3535
import com.example.compose.snippets.components.CardExamples
36+
import com.example.compose.snippets.components.CarouselExamples
3637
import com.example.compose.snippets.components.CheckboxExamples
3738
import com.example.compose.snippets.components.ChipExamples
3839
import com.example.compose.snippets.components.ComponentsScreen
@@ -109,6 +110,7 @@ class SnippetsActivity : ComponentActivity() {
109110
TopComponentsDestination.PartialBottomSheet -> PartialBottomSheet()
110111
TopComponentsDestination.TimePickerExamples -> TimePickerExamples()
111112
TopComponentsDestination.DatePickerExamples -> DatePickerExamples()
113+
TopComponentsDestination.CarouselExamples -> CarouselExamples()
112114
}
113115
}
114116
}
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/*
2+
* Copyright 2024 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+
* https://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 com.example.compose.snippets.components
18+
19+
import androidx.annotation.DrawableRes
20+
import androidx.compose.foundation.Image
21+
import androidx.compose.foundation.layout.Column
22+
import androidx.compose.foundation.layout.PaddingValues
23+
import androidx.compose.foundation.layout.fillMaxWidth
24+
import androidx.compose.foundation.layout.height
25+
import androidx.compose.foundation.layout.padding
26+
import androidx.compose.foundation.layout.wrapContentHeight
27+
import androidx.compose.material3.ExperimentalMaterial3Api
28+
import androidx.compose.material3.MaterialTheme
29+
import androidx.compose.material3.carousel.HorizontalMultiBrowseCarousel
30+
import androidx.compose.material3.carousel.HorizontalUncontainedCarousel
31+
import androidx.compose.material3.carousel.rememberCarouselState
32+
import androidx.compose.runtime.Composable
33+
import androidx.compose.runtime.remember
34+
import androidx.compose.ui.Modifier
35+
import androidx.compose.ui.layout.ContentScale
36+
import androidx.compose.ui.res.painterResource
37+
import androidx.compose.ui.tooling.preview.Preview
38+
import androidx.compose.ui.unit.dp
39+
import com.example.compose.snippets.R
40+
41+
@OptIn(ExperimentalMaterial3Api::class)
42+
@Preview
43+
// [START android_compose_carousel_multi_browse_basic]
44+
@Composable
45+
fun CarouselExample_MultiBrowse() {
46+
data class CarouselItem(
47+
val id: Int,
48+
@DrawableRes val imageResId: Int,
49+
val contentDescription: String
50+
)
51+
52+
val items = remember {
53+
listOf(
54+
CarouselItem(0, R.drawable.cupcake, "cupcake"),
55+
CarouselItem(1, R.drawable.donut, "donut"),
56+
CarouselItem(2, R.drawable.eclair, "eclair"),
57+
CarouselItem(3, R.drawable.froyo, "froyo"),
58+
CarouselItem(4, R.drawable.gingerbread, "gingerbread"),
59+
)
60+
}
61+
62+
HorizontalMultiBrowseCarousel(
63+
state = rememberCarouselState { items.count() },
64+
modifier = Modifier
65+
.fillMaxWidth()
66+
.wrapContentHeight()
67+
.padding(top = 16.dp, bottom = 16.dp),
68+
preferredItemWidth = 186.dp,
69+
itemSpacing = 8.dp,
70+
contentPadding = PaddingValues(horizontal = 16.dp)
71+
) { i ->
72+
val item = items[i]
73+
Image(
74+
modifier = Modifier
75+
.height(205.dp)
76+
.maskClip(MaterialTheme.shapes.extraLarge),
77+
painter = painterResource(id = item.imageResId),
78+
contentDescription = item.contentDescription,
79+
contentScale = ContentScale.Crop
80+
)
81+
}
82+
}
83+
// [END android_compose_carousel_multi_browse_basic]
84+
85+
@OptIn(ExperimentalMaterial3Api::class)
86+
@Preview
87+
// [START android_compose_carousel_uncontained_basic]
88+
@Composable
89+
fun CarouselExample() {
90+
data class CarouselItem(
91+
val id: Int,
92+
@DrawableRes val imageResId: Int,
93+
val contentDescription: String
94+
)
95+
96+
val carouselItems = remember {
97+
listOf(
98+
CarouselItem(0, R.drawable.cupcake, "cupcake"),
99+
CarouselItem(1, R.drawable.donut, "donut"),
100+
CarouselItem(2, R.drawable.eclair, "eclair"),
101+
CarouselItem(3, R.drawable.froyo, "froyo"),
102+
CarouselItem(4, R.drawable.gingerbread, "gingerbread"),
103+
)
104+
}
105+
106+
HorizontalUncontainedCarousel(
107+
state = rememberCarouselState { carouselItems.count() },
108+
modifier = Modifier
109+
.fillMaxWidth()
110+
.wrapContentHeight()
111+
.padding(top = 16.dp, bottom = 16.dp),
112+
itemWidth = 186.dp,
113+
itemSpacing = 8.dp,
114+
contentPadding = PaddingValues(horizontal = 16.dp)
115+
) { i ->
116+
val item = carouselItems[i]
117+
Image(
118+
modifier = Modifier
119+
.height(205.dp)
120+
.maskClip(MaterialTheme.shapes.extraLarge),
121+
painter = painterResource(id = item.imageResId),
122+
contentDescription = item.contentDescription,
123+
contentScale = ContentScale.Crop
124+
)
125+
}
126+
}
127+
// [END android_compose_carousel_uncontained_basic]
128+
129+
@Preview
130+
@Composable
131+
fun CarouselExamples() {
132+
Column {
133+
CarouselExample()
134+
CarouselExample_MultiBrowse()
135+
}
136+
}

compose/snippets/src/main/java/com/example/compose/snippets/components/ComponentsScreen.kt

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,59 @@
1616

1717
package com.example.compose.snippets.components
1818

19+
import androidx.compose.foundation.clickable
1920
import androidx.compose.foundation.layout.Arrangement
2021
import androidx.compose.foundation.layout.fillMaxSize
2122
import androidx.compose.foundation.layout.padding
2223
import androidx.compose.foundation.lazy.LazyColumn
2324
import androidx.compose.foundation.lazy.items
24-
import androidx.compose.material3.Button
25+
import androidx.compose.material3.ExperimentalMaterial3Api
26+
import androidx.compose.material3.ListItem
27+
import androidx.compose.material3.Scaffold
2528
import androidx.compose.material3.Text
29+
import androidx.compose.material3.TopAppBar
2630
import androidx.compose.runtime.Composable
2731
import androidx.compose.ui.Alignment
2832
import androidx.compose.ui.Modifier
2933
import androidx.compose.ui.unit.dp
3034
import com.example.compose.snippets.navigation.TopComponentsDestination
3135

36+
@OptIn(ExperimentalMaterial3Api::class)
3237
@Composable
3338
fun ComponentsScreen(
3439
navigate: (TopComponentsDestination) -> Unit
3540
) {
36-
LazyColumn(
37-
modifier = Modifier
38-
.padding(16.dp)
39-
.fillMaxSize(),
40-
verticalArrangement = Arrangement.spacedBy(8.dp),
41-
horizontalAlignment = Alignment.CenterHorizontally,
42-
) {
43-
items(TopComponentsDestination.entries) { destination ->
44-
NavigationItem(destination) {
45-
navigate(
46-
destination
47-
)
41+
Scaffold(topBar = {
42+
TopAppBar(title = {
43+
Text("Common Components")
44+
})
45+
}, content = { padding ->
46+
LazyColumn(
47+
modifier = Modifier
48+
.padding(padding)
49+
.fillMaxSize(),
50+
verticalArrangement = Arrangement.spacedBy(8.dp),
51+
horizontalAlignment = Alignment.CenterHorizontally,
52+
) {
53+
items(TopComponentsDestination.entries) { destination ->
54+
NavigationItem(destination) {
55+
navigate(
56+
destination
57+
)
58+
}
4859
}
4960
}
50-
}
61+
})
5162
}
5263

5364
@Composable
5465
fun NavigationItem(destination: TopComponentsDestination, onClick: () -> Unit) {
55-
Button(
56-
onClick = { onClick() }
57-
) {
58-
Text(destination.title)
59-
}
66+
ListItem(
67+
headlineContent = {
68+
Text(destination.title)
69+
},
70+
modifier = Modifier.clickable {
71+
onClick()
72+
}
73+
)
6074
}

compose/snippets/src/main/java/com/example/compose/snippets/landing/LandingScreen.kt

Lines changed: 23 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -18,56 +18,45 @@ package com.example.compose.snippets.landing
1818

1919
import androidx.compose.foundation.clickable
2020
import androidx.compose.foundation.layout.Arrangement
21-
import androidx.compose.foundation.layout.Box
22-
import androidx.compose.foundation.layout.Column
2321
import androidx.compose.foundation.layout.fillMaxSize
24-
import androidx.compose.foundation.layout.fillMaxWidth
2522
import androidx.compose.foundation.layout.heightIn
2623
import androidx.compose.foundation.layout.padding
2724
import androidx.compose.foundation.lazy.LazyColumn
2825
import androidx.compose.foundation.lazy.items
29-
import androidx.compose.material3.HorizontalDivider
26+
import androidx.compose.material3.ExperimentalMaterial3Api
27+
import androidx.compose.material3.ListItem
28+
import androidx.compose.material3.Scaffold
3029
import androidx.compose.material3.Text
30+
import androidx.compose.material3.TopAppBar
3131
import androidx.compose.runtime.Composable
3232
import androidx.compose.ui.Alignment
3333
import androidx.compose.ui.Modifier
34-
import androidx.compose.ui.text.TextStyle
35-
import androidx.compose.ui.text.font.FontWeight
36-
import androidx.compose.ui.text.style.TextAlign
3734
import androidx.compose.ui.unit.dp
38-
import androidx.compose.ui.unit.sp
3935
import com.example.compose.snippets.navigation.Destination
4036

37+
@OptIn(ExperimentalMaterial3Api::class)
4138
@Composable
4239
fun LandingScreen(
4340
navigate: (Destination) -> Unit
4441
) {
45-
Column(
46-
modifier = Modifier
47-
.padding(16.dp)
48-
.fillMaxSize(),
49-
verticalArrangement = Arrangement.spacedBy(24.dp),
50-
) {
51-
Text(
52-
modifier = Modifier.fillMaxWidth(),
53-
style = TextStyle(
54-
fontSize = 24.sp,
55-
fontWeight = FontWeight.Bold,
56-
textAlign = TextAlign.Center,
57-
),
58-
text = "Android snippets",
59-
)
60-
Text(
61-
text = "Use the following buttons to view a selection of the snippets used in the Android documentation."
62-
)
63-
NavigationItems { navigate(it) }
42+
Scaffold(
43+
topBar = {
44+
TopAppBar(title = {
45+
Text(text = "Android snippets",)
46+
})
47+
}
48+
) { padding ->
49+
NavigationItems(modifier = Modifier.padding(padding)) { navigate(it) }
6450
}
6551
}
6652

6753
@Composable
68-
fun NavigationItems(navigate: (Destination) -> Unit) {
54+
fun NavigationItems(
55+
modifier: Modifier = Modifier,
56+
navigate: (Destination) -> Unit
57+
) {
6958
LazyColumn(
70-
modifier = Modifier
59+
modifier = modifier
7160
.fillMaxSize(),
7261
verticalArrangement = Arrangement.spacedBy(8.dp),
7362
horizontalAlignment = Alignment.CenterHorizontally,
@@ -84,14 +73,14 @@ fun NavigationItems(navigate: (Destination) -> Unit) {
8473

8574
@Composable
8675
fun NavigationItem(destination: Destination, onClick: () -> Unit) {
87-
Box(
76+
ListItem(
77+
headlineContent = {
78+
Text(destination.title)
79+
},
8880
modifier = Modifier
8981
.heightIn(min = 48.dp)
9082
.clickable {
9183
onClick()
9284
}
93-
) {
94-
Text(destination.title)
95-
HorizontalDivider(modifier = Modifier.align(Alignment.BottomCenter))
96-
}
85+
)
9786
}

compose/snippets/src/main/java/com/example/compose/snippets/navigation/Destination.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,5 @@ enum class TopComponentsDestination(val route: String, val title: String) {
4444
PartialBottomSheet("partialBottomSheets", "Partial Bottom Sheet"),
4545
TimePickerExamples("timePickerExamples", "Time Pickers"),
4646
DatePickerExamples("datePickerExamples", "Date Pickers"),
47+
CarouselExamples("carouselExamples", "Carousel")
4748
}

0 commit comments

Comments
 (0)