Skip to content

Commit

Permalink
Navigation 구현 (#17)
Browse files Browse the repository at this point in the history
* add : navigation 구현

* chore : 선택,비선택 아이콘을 없애고 단일 아이콘에 색상 변경만으로 선택여부 지정

* chore : 클릭시 인디케이션 제거

* chore : 리뷰 반영

* delete : 불필요 home.xml 제거

* chore : deploymentTargetSelector.xml gitignore 시킴

* chore : Divider 추가

* chore : 리뷰 반영

* 피드백 반영
  • Loading branch information
Gael-Android authored Jan 27, 2025
1 parent b884ab5 commit 6e4b1e7
Show file tree
Hide file tree
Showing 3 changed files with 162 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
/.idea/deploymentTargetSelector.xml
.DS_Store
/build
/captures
Expand Down
47 changes: 47 additions & 0 deletions app/src/main/kotlin/com/yourssu/handy/demo/NavigationPreview.kt
Original file line number Diff line number Diff line change
@@ -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 = {}
)
}
}
114 changes: 114 additions & 0 deletions compose/src/main/kotlin/com/yourssu/handy/compose/Navigation.kt
Original file line number Diff line number Diff line change
@@ -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<BottomNavItem>,
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) }
)
}
}
}
}

0 comments on commit 6e4b1e7

Please sign in to comment.