Jetpack Compose 13: Paging and Scrolling with Examples

Jetpack Compose 13: Paging and Scrolling with Examples

TB

Teqani Blogs

Writer at Teqani

June 6, 20252 min read

Introduction

This article explores how to implement smooth and customizable paging and scrolling in Jetpack Compose. We'll delve into using built-in components and the Accompanist library to create engaging UIs, perfect for carousels, tabbed views, and snap-scrolling lists. This will enhance your app's user experience.



تستكشف هذه المقالة كيفية تنفيذ ترقيم الصفحات والتمرير بسلاسة وقابلية للتخصيص في Jetpack Compose. سنتعمق في استخدام المكونات المضمنة ومكتبة Accompanist لإنشاء واجهات مستخدم جذابة، مثالية للدوارات وعروض علامات التبويب وقوائم التمرير السريع. سيعزز هذا تجربة المستخدم لتطبيقك.



HorizontalPager / VerticalPager — Swipeable Page Layouts

The HorizontalPager and VerticalPager composables from the Accompanist library allow you to create swipeable page layouts. These are great for creating onboarding flows, image galleries, or any UI where you want users to easily swipe between pages.



تتيح لك مكونات HorizontalPager و VerticalPager القابلة للتركيب من مكتبة Accompanist إنشاء تخطيطات صفحات قابلة للتمرير. هذه رائعة لإنشاء تدفقات الإعداد أو معارض الصور أو أي واجهة مستخدم تريد أن يتمكن المستخدمون فيها من التمرير بسهولة بين الصفحات.



HorizontalPager Example

@OptIn(ExperimentalPagerApi::class)
@Composable
fun HorizontalPagerExample() {
 val pagerState = rememberPagerState()
 Column {
 HorizontalPager(count = 5, state = pagerState) { page ->
 Box(
 Modifier
 .fillMaxSize()
 .background(Color(0xFFBBDEFB + page * 1000))
 ) {
 Text("Page $page", Modifier.align(Alignment.Center))
 }
 }
 }
}


VerticalPager Example

@OptIn(ExperimentalPagerApi::class)
@Composable
fun VerticalPagerExample() {
 val pagerState = rememberPagerState()
 VerticalPager(
 count = 5,
 state = pagerState,
 modifier = Modifier
 .fillMaxSize()
 ) { page ->
 Box(
 modifier = Modifier
 .fillMaxSize()
 .background(
 when (page % 3) {
 0 -> Color(0xFFE3F2FD)
 1 -> Color(0xFFC8E6C9)
 else -> Color(0xFFFFF9C4)
 }
 ),
 contentAlignment = Alignment.Center
 ) {
 Text(text = "Page $page", fontSize = 32.sp, fontWeight = FontWeight.Bold)
 }
 }
}


PagerTabIndicator  — Tab + Pager Combo

The PagerTabIndicator is a composable that combines a tab row with a pager, allowing users to navigate between pages by tapping on tabs or swiping. This provides a familiar and intuitive navigation experience.



PagerTabIndicator هو عنصر قابل للتركيب يجمع بين صف علامات التبويب وجهاز ترحيل، مما يسمح للمستخدمين بالتنقل بين الصفحات عن طريق النقر على علامات التبويب أو التمرير السريع. يوفر هذا تجربة تنقل مألوفة وبديهية.



@OptIn(ExperimentalPagerApi::class)
@Composable
fun PagerWithTabs() {
 val pagerState = rememberPagerState()
 val tabTitles = listOf("Home", "Profile", "Settings")
 Column {
 TabRow(selectedTabIndex = pagerState.currentPage) {
 tabTitles.forEachIndexed { index, title ->
 Tab(
 selected = pagerState.currentPage == index,
 onClick = { CoroutineScope(Dispatchers.Main).launch { pagerState.animateScrollToPage(index) } },
 text = { Text(title) }
 )
 }
 }
 HorizontalPager(count = tabTitles.size, state = pagerState) { page ->
 Box(Modifier.fillMaxSize().padding(16.dp)) {
 Text("Content for ${tabTitles[page]}")
 }
 }
 }
}


Snapper (Accompanist) — Snap Scrolling in Lazy Lists

Snapper is a library that provides snap scrolling behavior for LazyRow and LazyColumn. This allows you to create carousel-like experiences where items snap into place as the user scrolls. It greatly improves the usability of your scrollable lists.



Snapper هي مكتبة توفر سلوك التمرير السريع لـ LazyRow و LazyColumn. يتيح لك هذا إنشاء تجارب تشبه الدوار حيث تستقر العناصر في مكانها أثناء قيام المستخدم بالتمرير. إنه يحسن بشكل كبير من سهولة استخدام قوائم التمرير الخاصة بك.



Snapper LazyRow Example

@OptIn(ExperimentalSnapperApi::class)
@Composable
fun SnapperLazyRow() {
 val list = (1..10).toList()
 val lazyListState = rememberLazyListState()
 LazyRow(
 state = lazyListState,
 flingBehavior = rememberSnapperFlingBehavior(lazyListState),
 contentPadding = PaddingValues(horizontal = 16.dp)
 ) {
 items(list.size) { index ->
 Card(
 Modifier
 .width(200.dp)
 .height(150.dp)
 .padding(8.dp)
 ) {
 Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
 Text("Item $index")
 }
 }
 }
 }
}


Snapper LazyColumn Example

@OptIn(ExperimentalSnapperApi::class)
@Composable
fun SnapperLazyColumnExample() {
 val items = (1..10).toList()
 val listState = rememberLazyListState()
 LazyColumn(
 state = listState,
 flingBehavior = rememberSnapperFlingBehavior(lazyListState = listState),
 contentPadding = PaddingValues(vertical = 16.dp),
 verticalArrangement = Arrangement.spacedBy(16.dp),
 modifier = Modifier.fillMaxSize()
 ) {
 items(items.size) { index ->
 Card(
 modifier = Modifier
 .fillMaxWidth()
 .height(120.dp)
 .padding(horizontal = 16.dp),
 elevation = CardDefaults.cardElevation(4.dp)
 ) {
 Box(contentAlignment = Alignment.Center) {
 Text("Item #${items[index]}", fontSize = 20.sp)
 }
 }
 }
 }
}


Conclusion

Jetpack Compose provides powerful tools for creating engaging and user-friendly scrolling experiences. By leveraging the HorizontalPager, VerticalPager, and Snapper libraries, you can create a wide variety of UI patterns that enhance your app's usability and appeal.



يوفر Jetpack Compose أدوات قوية لإنشاء تجارب تمرير جذابة وسهلة الاستخدام. من خلال الاستفادة من مكتبات HorizontalPager و VerticalPager و Snapper، يمكنك إنشاء مجموعة متنوعة من أنماط واجهة المستخدم التي تعزز سهولة استخدام تطبيقك وجاذبيته.

TB

Teqani Blogs

Verified
Writer at Teqani

Senior Software Engineer with 10 years of experience

June 6, 2025
Teqani Certified

All blogs are certified by our company and reviewed by our specialists
Issue Number: #29f8aedf-e035-43c9-adc6-fdba7e744c4f