Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Navigation 구현 #17

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
48 changes: 48 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,48 @@
package com.yourssu.handy.demo

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
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 = {}
)
}
}
110 changes: 110 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,110 @@
package com.yourssu.handy.compose

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.Divider
import com.yourssu.handy.compose.foundation.HandyTypography

/**
* BottomNavItem : 하단 네비게이션 바의 아이템을 정의하는 데이터 클래스 입니다.
*
* @param icon 아이템의 아이콘
* @param label 아이템의 라벨
*/
data class BottomNavItem(
val icon: ImageVector,
val label: String?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

기본값 null로 되어 있는 게 더 좋을 것 같아요

)

/**
* BottomNavItem : 하단 네비게이션 바의 아이템 Composable 함수 입니다.
*
* @param item 하단 네비게이션 바의 아이템
* @param isSelected 선택되었는지 여부
* @param onClick 클릭 시 실행되는 함수
* @param modifier Modifier
*/
@Composable
private fun BottomNavItem(
item: BottomNavItem,
isSelected: Boolean,
cometj03 marked this conversation as resolved.
Show resolved Hide resolved
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,
)

Comment on lines +58 to +63
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아이콘 색상도 지정해줘야 할 것 같네요

if (item.label != null) {
Text(
text = item.label,
style = HandyTypography.C1Rg11,
color = color
)
}
}
}

/**
* Navigation : 하단 네비게이션 바 Composable 함수 입니다.
*
* @param items 하단 네비게이션 바의 아이템 리스트
* @param selectedIndex 선택된 아이템의 인덱스
* @param onItemSelected 아이템 선택 시 실행되는 함수
*/
@Composable
fun Navigation(
items: List<BottomNavItem>,
selectedIndex: Int,
onItemSelected: (Int) -> Unit
) {
Comment on lines +81 to +86
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

modifier 파라미터가 빠진 것 같네요

require(items.size in 3..5) { "Items size must be between 3 and 5" }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이렇게 items수를 강제하는 건 좋은 것 같긴한데 require를 사용하게 되면
해당 컴포넌트로 개발 진행 시에 item수 미달, 초과로 preview단에서 오류가 뜨면 추적이 어려울 것 같은데 어떻게 생각하시나요??
item을 6개 넣으면 preview render오류가 뜨긴하지만 메시지는 보이지 않네요,,
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image
이슈 패널 열면 뜨고 에뮬레이터에 돌리면 에러가 납니다.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require나 check로 체크하는 건 주석에 명시해주세요! -> 핸디 컨벤션에 추가해둘게요


Column(
modifier = Modifier
.fillMaxWidth()
.height(56.dp),
) {
Divider(dividerThickness = DividerThickness.ONE)
Comment on lines +88 to +94
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surface로 감싸는 게 좋을 것 같습니다! 지금은 배경이 투명일 것 같네용

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) }
)
}
}
}
}