안드로이드 앱 개발 공부/jetpack Compose

[jetpack compose] 제트팩 컴포즈로 탭 만들기

플래시🦥 2023. 3. 7.
반응형

유튜브에서 한 외국인의 강의를 듣고 만들었다. 에스파냐어를 사용해서 무슨 말인지는 못 알아 들었지만.. 직접 공부하면서 코드를 분석해서 만들어봤땅.

 

1. 메인 액티비티 : MainActivity.kt

Tabs_principle함수는 탭을 어떻게 구성할지를 작성한 코드이다. 호출해서 적용한다.

class MainActivity : ComponentActivity() {
    @SuppressLint("ResourceAsColor")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            StickyMemoryTheme {
                Surface {
                    Tabs_principle()
                }
            }
        }
    }
}

2-1. 만들고 싶은 탭 : allView.kt / todoView.kt /  memoView.kt / ddayView.kt

*preview는 단어 뜻 그대로 미리 결과를 보기 위한 코드이다. 

탭의 레이아웃은 그냥 어떤 레이아웃인지 파악할 용도로만 구성해 두었다.

만들고 싶은 탭만큼 만들어야 한다. 

나는 코드가 모두 동일하므로 하나의 코드 예시만 올려두었다. 

@Composable
fun allview(){
    Column(
        modifier = Modifier
            .fillMaxSize()
            .wrapContentSize(Alignment.Center)
    ) {
        Text("All",
            style = MaterialTheme.typography.h1
        )
    }
}

@Preview(showBackground = true)
@Composable
fun PreviewAllview(){
    StickyMemoryTheme {
        allview()
    }
}

 

 

3. 탭 아이템을 구성 : tabs_items.kt

여기서는 탭 아이템을 구성한다. 

탭별로 변수를 선언해서 어떤 뷰를 보여줄 것인지를 정해준다. 

typealias MyFunc= @Composable ()-> Unit
sealed class tabs_items(
    var title : String,
    var screen : MyFunc
){
    object item_all : tabs_items("ALL",{ allview()})
    object item_todo : tabs_items("Todo",{ todoview() })
    object item_dday : tabs_items("D-day",{ ddayview() })
    object item_memo : tabs_items("Memo",{ memoview() })
}

sealed class는 추상클래스로 상속받는 자식 클래스의 종류를 제한하는 특징을 가진 클래스라고 한다. 컴파일러에서 sealed class의 자식클래스가 어떤 것이 있는지 알 수 있다. 

 

난 아이콘은 넣어주지 않을 것이라 title과 뷰만 정했지만 아이콘을 원하면 위 클래스에 아이콘 변수 추가해서 지정해 주면 된다. 

4.Tabs_principle.kt

여기서는 지금까지 만들어둔 것들을 가지고 탭을 완성시켜 주는 것이라고 보면 된다. 

Tabs_principle() 함수에서 이전 tabs_items의 요소들을 가지고 탭 리스트를 만들어 주고, Column안에 그 탭 리스트와 pager를 생성하고 기억하기 위한 pagerState함수를 가지고 탭구성을 하는 함수를 호출한다. 

@OptIn(ExperimentalPagerApi::class)
@Composable
fun Tabs_principle() {
    val tabs = listOf(
        tabs_items.item_all,
        tabs_items.item_todo,
        tabs_items.item_dday,
        tabs_items.item_memo
    )
    val pagerState = rememberPagerState()
    Column {
        Tabs(tabs, pagerState)
        Tabs_content(tabs, pagerState)
    }
}


@OptIn(ExperimentalPagerApi::class)
@Composable
fun Tabs(tabs: List<tabs_items>, pagerState: PagerState) {
    val scope = rememberCoroutineScope()
    TabRow(
        modifier = Modifier
            .height(60.dp),
        selectedTabIndex = pagerState.currentPage,
        contentColor = colorResource(id = R.color.moreOrange)
    ) {
        tabs.forEachIndexed { index, tabsItems ->
            LeadingIconTab(
                selectedContentColor = colorResource(id = R.color.moreOrange),
                unselectedContentColor = colorResource(id = R.color.littleOrange),
                selected = pagerState.currentPage == index,
                onClick = {
                    scope.launch {
                        pagerState.animateScrollToPage(index)
                    }
                },
                icon = {},
                text = { Text(tabsItems.title, fontWeight = FontWeight.Bold) }
            )
        }
    }
}

@OptIn(ExperimentalPagerApi::class)
@Composable
fun Tabs_content(tabs: List<tabs_items>, pagerState: PagerState) {
    HorizontalPager(
        state = pagerState,
        count = tabs.size
    ) { page ->
        tabs[page].screen()
    }
}

Tabs() 함수에서는 탭의 구성과 클릭했을 때 동작을 구성하고 

Tabs_content() 함수에서는 HorizontalPager를 만들어주는 코드이다. 

contentColor = colorResource(id = R.color.black)

여기 선택된 탭의 밑에 있는 밑줄 색상을 변경하는 코드이다. 

 

 

selectedContentColor = colorResource(id = R.color.moreOrange),
unselectedContentColor = colorResource(id = R.color.littleOrange),

그리고 이 두 개는 선택되었을 때와 아닐 때 각 색상을 선택할 수 있는 코드이다. 


그 결과~

 

728x90
반응형

댓글