Tab이란?

일반적으로 모바일 핸드폰은 화면의 크기가 작아서 하나의 화면에 많은 구성요소를 넣으면 성능이나 사용성 면에서 좋지 않다.
안드로이드의 경우도 하나의 액티비티를 분리시켜 하나의 화면에 보이는 뷰의 개수를 줄이는 것이 좋다.
Tab과 Navigation(하단)은 위와 같은 상황을 해결할 수 있도록 도와준다. Tab은 상단(액션바)에 위치한다.

아래의 영상은 Tab과 ViewPager을 같이 사용해 만든 영상이다.

androidTab

build.gradle.kts

// viewPager2
implementation("com.tbuonomo:dotsindicator:5.0")
implementation("androidx.compose.foundation:foundation:1.4.0")

Tab Composable

  • TabItem
data class Tabltem(
    val unselectedIcon: ImageVector,
    val selectedIcon: ImageVector
)
val tabltems = listOf(
    Tabltem(
        unselectedIcon = Icons.Outlined.Map,
        selectedIcon = Icons.Filled.Map
    ),
    Tabltem(
        unselectedIcon = Icons.Outlined.Schedule,
        selectedIcon = Icons.Filled.Schedule
    ),
    Tabltem(
        unselectedIcon = Icons.Outlined.Delete,
        selectedIcon = Icons.Filled.Delete
    ),
)

var selectedTabIndex by remember {
    mutableIntStateOf(0) // or use mutableStateOf(0)
}
val pagerState = rememberPagerState { tabltems.size }

// 스와이프를 했을 때 Tab의 index도 변화시켜는 코드
LaunchedEffect(pagerState.currentPage) {
    selectedTabIndex = pagerState.currentPage
}

Column(modifier = Modifier.fillMaxSize()) {
    TabRow(
        selectedTabIndex = selectedTabIndex,
    ) {
        tabltems.forEachIndexed { index, item ->
            Tab(
                selected = (selectedTabIndex == index),
                icon = {
                    Icon(
                        imageVector = if (index == selectedTabIndex) item.selectedIcon else item.unselectedIcon,
                        contentDescription = null,
                        tint = Color.Black
                    )
                },
                onClick = {
                    selectedTabIndex = index
                    coroutineScope.launch {
                        pagerState.animateScrollToPage(
                            selectedTabIndex
                        )
                    }
                })
        }
    }
    HorizontalPager(state = pagerState, modifier = Modifier.fillMaxSize()) { index ->
        when (index) {
            0 -> MapScreen(mapViewModel = mapViewModel, cameraLauncher = cameraLauncher)
            1 -> RecordScreen(
                mapViewModel = mapViewModel,
                cameraLauncher = cameraLauncher
            )

            2 -> TrashListScreen()
        }
    }
}

tabltems은 Tab 컴포저블에 각각해당하는 아이콘들의 리스트이다.
selectedTabIndex은 현재 활성화된 Tab의 인덱스 정보이다. TabRow 컴포저블에 등록시켜놓는다.
클릭 했을 때 다른 화면으로 넘어가게 된다. 이 때 pagerState 또한 연결시켜야 Swipe했을 때 정상적으로 작동된다.
HorizontalPager 컴포저블은 가로로 Swipe 가능하도록 지원하는 viewPager이다. 당연히 pagerState를 등록시켜야 한다.
pagerState.isScrollInProgress는 현재 페이지 스와이프 중이면 true, 스와이프가 완료되면 false로 나타낸다.
pagerState.animateScrollToPage( selectedTabIndex)는 선택한 탭의 페이지로 부드럽게 스크롤하는 메서드이다. 이 메서드를 호출하면 지정된 인덱스의 페이지로 자연스럽게 애니메이션화된 스크롤이 이루어진다.

Reference

Tab의 정의
Tab과 viewPager 함께 사용