From 6e4b1e7bfb942fdeaa1cb0158c833d0d05e3f5b2 Mon Sep 17 00:00:00 2001 From: Gael-Android <84790707+Gael-Android@users.noreply.github.com> Date: Mon, 27 Jan 2025 16:07:52 +0900 Subject: [PATCH] =?UTF-8?q?Navigation=20=EA=B5=AC=ED=98=84=20(#17)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add : navigation 구현 * chore : 선택,비선택 아이콘을 없애고 단일 아이콘에 색상 변경만으로 선택여부 지정 * chore : 클릭시 인디케이션 제거 * chore : 리뷰 반영 * delete : 불필요 home.xml 제거 * chore : deploymentTargetSelector.xml gitignore 시킴 * chore : Divider 추가 * chore : 리뷰 반영 * 피드백 반영 --- .gitignore | 1 + .../yourssu/handy/demo/NavigationPreview.kt | 47 ++++++++ .../com/yourssu/handy/compose/Navigation.kt | 114 ++++++++++++++++++ 3 files changed, 162 insertions(+) create mode 100644 app/src/main/kotlin/com/yourssu/handy/demo/NavigationPreview.kt create mode 100644 compose/src/main/kotlin/com/yourssu/handy/compose/Navigation.kt diff --git a/.gitignore b/.gitignore index f58c8037..7778bca7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ /.idea/workspace.xml /.idea/navEditor.xml /.idea/assetWizardSettings.xml +/.idea/deploymentTargetSelector.xml .DS_Store /build /captures diff --git a/app/src/main/kotlin/com/yourssu/handy/demo/NavigationPreview.kt b/app/src/main/kotlin/com/yourssu/handy/demo/NavigationPreview.kt new file mode 100644 index 00000000..be788fc4 --- /dev/null +++ b/app/src/main/kotlin/com/yourssu/handy/demo/NavigationPreview.kt @@ -0,0 +1,47 @@ +package com.yourssu.handy.demo + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.yourssu.handy.compose.BottomNavItem +import com.yourssu.handy.compose.Navigation +import com.yourssu.handy.compose.icons.HandyIcons +import com.yourssu.handy.compose.icons.filled.Home + +@Preview(showBackground = true) +@Composable +fun NavigationPreview() { + val items = listOf( + BottomNavItem( + icon = HandyIcons.Filled.Home, + label = "Label" + ), + BottomNavItem( + icon = HandyIcons.Filled.Home, + label = "Label" + ), + BottomNavItem( + icon = HandyIcons.Filled.Home, + label = "Label" + ), + BottomNavItem( + icon = HandyIcons.Filled.Home, + label = "Label" + ), + BottomNavItem( + icon = HandyIcons.Filled.Home, + label = "Label" + ), + ) + + Column { + Spacer(modifier = Modifier.weight(1f)) + Navigation( + items = items, + selectedIndex = 0, + onItemSelected = {} + ) + } +} \ No newline at end of file diff --git a/compose/src/main/kotlin/com/yourssu/handy/compose/Navigation.kt b/compose/src/main/kotlin/com/yourssu/handy/compose/Navigation.kt new file mode 100644 index 00000000..b3ce9f35 --- /dev/null +++ b/compose/src/main/kotlin/com/yourssu/handy/compose/Navigation.kt @@ -0,0 +1,114 @@ +package com.yourssu.handy.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.unit.dp +import com.yourssu.handy.compose.foundation.HandyTypography + +/** + * BottomNavItem : 하단 네비게이션 바의 아이템을 정의하는 데이터 클래스 입니다. + * + * @param icon 아이템의 아이콘 + * @param label 아이템의 라벨 + */ +data class BottomNavItem( + val icon: ImageVector, + val label: String? = null +) + +/** + * BottomNavItem : 하단 네비게이션 바의 아이템 Composable 함수 입니다. + * + * @param item 하단 네비게이션 바의 아이템 + * @param isSelected 선택되었는지 여부 + * @param onClick 클릭 시 실행되는 함수 + * @param modifier Modifier + */ +@Composable +private fun BottomNavItem( + item: BottomNavItem, + isSelected: Boolean, + onClick: () -> Unit, + modifier: Modifier = Modifier +) { + val color = + if (isSelected) HandyTheme.colors.textBasicPrimary else HandyTheme.colors.textBasicDisabled + + Column( + modifier = modifier + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = onClick + ), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center + ) { + Icon( + item.icon, + iconSize = IconSize.M, + tint = color + ) + + if (item.label != null) { + Text( + text = item.label, + style = HandyTypography.C1Rg11, + color = color + ) + } + } +} + +/** + * Navigation : 하단 네비게이션 바 Composable 함수 입니다. + * + * @param items 하단 네비게이션 바의 아이템 리스트. item의 개수는 3개 이상 5개 이하여야 합니다. + * @param selectedIndex 선택된 아이템의 인덱스 + * @param onItemSelected 아이템 선택 시 실행되는 함수 + * + */ +@Composable +fun Navigation( + items: List, + selectedIndex: Int, + onItemSelected: (Int) -> Unit, + modifier: Modifier = Modifier +) { + require(items.size in 3..5) { "Items size must be between 3 and 5" } + + Surface( + modifier = modifier + .fillMaxWidth() + .height(56.dp) + .background(HandyTheme.colors.bgBasicDefault), + ) { + Divider(dividerThickness = DividerThickness.ONE) + Row( + modifier = Modifier.fillMaxSize(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + items.forEachIndexed { index, item -> + BottomNavItem( + item = item, + isSelected = index == selectedIndex, + modifier = Modifier.weight(1f), + onClick = { onItemSelected(index) } + ) + } + } + } +} \ No newline at end of file