Creating a Responsive Carousel in Jetpack Compose
A carousel is a UI component used to display a series of content items (like images, cards, or text) in a scrollable horizontal (or sometimes vertical) format. Users can navigate through these items either manually (e.g., by swiping or clicking on navigation buttons) or automatically (e.g., with auto-scrolling).
Key Characteristics:
Horizontal Scrolling: Items are arranged in a row and can be swiped or scrolled horizontally.
Navigation Controls: Carousels often have left/right arrow buttons or pagination dots to indicate the current item and navigate between them.
Auto-Sliding: Some carousels auto-advance through items after a set time.
Focus on Key Content: Commonly used for showcasing prominent items like banners, promotions, featured products, or image galleries.
Common Use Cases:
E-commerce: To highlight featured products or promotions.
Media Galleries: For image or video slideshows.
Hero Sections: On websites to display key messages, news, or announcements.
Content Recommendations: To show suggested items, like movies, articles, or blog posts.
Example:
On e-commerce websites like Amazon, a carousel is used to display a scrollable list of products under sections like "Recommended for You" or "Frequently Bought Together."
Creating a carousel in Jetpack Compose involves designing a scrollable list of items that users can swipe through horizontally. Here's a basic example of how to implement a carousel.
CarouselDemo
package com.codingbihar.composableskill
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun CarouselDemo() {
val imageList = listOf(
R.drawable.image1, // Replace with your drawable resources
R.drawable.image2,
R.drawable.image3
)
Column {
Text(
text = "Image Carousel",
fontSize = 20.sp,
modifier = Modifier.padding(16.dp)
)
CarouselWithControls(items = imageList)
}
}
@Composable
fun CarouselWithControls(items: List<Int>) {
var currentIndex by remember { androidx.compose.runtime.mutableIntStateOf(0) }
val coroutineScope = rememberCoroutineScope()
val listSize = items.size
Box(modifier = Modifier.fillMaxWidth()) {
LazyRow(
modifier = Modifier.fillMaxWidth(),
contentPadding = PaddingValues(horizontal = 16.dp),
horizontalArrangement = Arrangement.Center
) {
item {
CarouselItem(item = items[currentIndex])
}
}
// Left Arrow
IconButton(
onClick = {
currentIndex = (currentIndex - 1 + listSize) % listSize
},
modifier = Modifier
.align(Alignment.CenterStart)
.padding(8.dp)
) {
Text(
text = "<",
fontSize = 18.sp,
color = Color.White,
modifier = Modifier.padding(8.dp),
textAlign = TextAlign.Center
)
}
// Right Arrow
IconButton(
onClick = {
currentIndex = (currentIndex + 1) % listSize
},
modifier = Modifier
.align(Alignment.CenterEnd)
.padding(8.dp)
) {
Text(
text = ">",
fontSize = 18.sp,
color = Color.White,
modifier = Modifier.padding(8.dp),
textAlign = TextAlign.Center
)
}
}
// Auto-change using LaunchedEffect
LaunchedEffect(key1 = currentIndex) {
coroutineScope.launch {
delay(3000) // Auto-scroll interval (3 seconds)
currentIndex = (currentIndex + 1) % listSize
}
}
}
@Composable
fun CarouselItem(item: Int) {
Card(
modifier = Modifier
.width(300.dp)
.height(200.dp),
shape = RoundedCornerShape(12.dp),
colors = CardDefaults.cardColors(containerColor = Color.LightGray)
) {
Image(
painter = painterResource(id = item),
contentDescription = "Carousel item",
contentScale = ContentScale.Crop,
modifier = Modifier.fillMaxSize()
)
}
}
MainActivity
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
ComposableSkillTheme {
/* Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding)
)
}*/
// AutoSlidingCarouselDemo()
CarouselDemo()
}
}
}
}
Key Components:
LazyRow: Creates a horizontal, scrollable list.
CarouselItem: Represents each item in the carousel (e.g., an image or a card).
PaddingValues & Arrangement: Add spacing and padding for better visuals.
Card: Used to enhance the UI with rounded corners and shadows.
This basic example can be extended with additional features like snapping to items, indicators, or animations for a more polished carousel. Would you like help with adding any advanced functionality?