7월, 2024의 게시물 표시

Compose DatePickerDialog - 날짜 선택 제한

이미지
DatePickerDialog DatePickerDialog = DatePicker + Dialog 즉, 날짜를 선택할 수 있는 DatePicker를 Dialog 형태로 나타내는 컴포넌트이다. 그림1. DatePicker 사용자에게 특정 날짜를 입력 받기 위해서 사용자가 간단히 선택할 수 있는 UI를 제공하며 Dialog 형태로 나타나므로 공간을 낭비하지 않아서 날짜를 입력 받고자 할 때 유용하게 사용 할 수 있다. DatePickerDialog 구현 DatePickerDialog 부분을 살펴보기 전에 우선 UI 부분을 살펴보면 date : 선택한 날짜 showDatePicker : DatePickerDialog 보이기/숨기기 여부 판별 그림2. 버튼 클릭 시 Dialog Open var date by remember { mutableStateOf ( "Open date picker dialog" ) } var showDatePicker by remember { mutableStateOf ( false ) } if (showDatePicker) { MyDatePickerDialog ( onDateSelected = { date = it } , onDismiss = { showDatePicker = false } ) } Box ( modifier = Modifier. padding (innerPadding). fillMaxSize (), contentAlignment = Alignment. Center ) { Button ( onClick = { showDatePicker = true } ) { Text ( text = date) } } 버튼을 클릭하면 showDatePicker 변수를 true로 초기화하고 그에 따라서 정의한 MyDatePickerDialog 컴포저블 함수를 통해 DatePickerDialog가 나타나게 된다. MyDatePickerDialog 다...

Compose TextField, OutlinedTextField

이미지
TextField TextField는 문자나 숫자를 사용자가 키보드를 통하여 직접 작성하도록 하여 입력 받을 수 있는 컴포넌트이다. 자유롭게 작성이 가능하지만 키보드의 입력 타입을 제한하여 의도 된 형태로만 입력 할 수 있도록 제한을 할 수도 있다. 그림1. 숫자 입력 선택지가 제한된 경우에는 라디오 버튼이나 체크 박스를 사용할 수 있지만 그렇지 않은 경우도 많기 때문에 TextField가 많이 사용된다. TextField 구현 TextField를 구현하기에 앞서 우선 크게 나누면 TextField는 기본적인 TextField와 테두리가 있는 OutlinedTextField 2가지 가 있다. 이 두 TextField는 디자인 차이일 뿐 동일한 파라미터를 사용하고 구현하기 때문에 사용하는 화면 레이아웃에 맞는 것을 사용하면 된다. TextField 기본적인 TextField로 문자나 숫자를 입력 받을 수 있다. colors 파라미터에서 TextFieldDefaults.colors로 TextField의 배경색, 지시자 색, 포커스 여부에 따른 색 등을 지정 할 수 있는데 해당 예시에서는 unfocusedContainerColor를 Transparent로 지정하여서 TextField의 포커스가 없을 때는 색이 없지만, 선택하면 ContainerColor가 나타나는 것을 그림 1에서 볼 수 있다. 그림2. TextField TextField ( value = text, onValueChange = { setOnTextChange( it ) } , colors = TextFieldDefaults. colors ( // focusedContainerColor = Color.Transparent, unfocusedContainerColor = Color. Transparent , focusedIndicatorColor = Color. Green , unfocus...

Compose checkbox - 전체 선택 기능까지

이미지
Checkbox 체크 박스는 라디오 버튼이나 메뉴 박스와 같이 사용자에게 옵션을 선택할 수 있도록 제시하는 UI 이다. 체크 박스만의 특징을 말하면, 제시한 하나의 물음에 사용자가 여러가지 답을 선택할 수 있도록 하는 것 이다. 만약 좋아하는 음식을 묻는다면 그에 대한 대답이 여럿일 수 있기 때문에 체크 박스를 사용하면 된다. 그림1. Checkbox 특히 체크 박스는 라디오 버튼과 유사한데 라디오 버튼은 하나의 옵션만 선택이 가능하므로 하나의 답 만을 얻어야 한다면 라디오 버튼을 다수의 답을 얻어도 된다면 체크 박스 를 구분하여 사용하면 된다. Checkbox 구현 해당 예시에서는 기본적인 체크 박스 뿐만 아니라 체크 박스를 사용할 때 흔히 많이 사용되는 전체 체크 기능까지 알아보도록 하겠다. 먼저 사용할 변수들을 살펴보면 val sample = listOf ( "Meat" , "Bread" , "Snack" , "Drink" ) val checkList = remember { mutableStateListOf ( false , false , false , false ) } val allChecked = when { checkList. all { it } -> ToggleableState. On checkList. none { it } -> ToggleableState. Off else -> ToggleableState. Indeterminate } sample : Checkbox 옵션들 checkList : Checkbox 각 옵션 체크 여부 allChecked : 전체 선택의 상태 값 여기서 allChecked 보면 checkList 값에 따라 즉, 모든 체크 박스들의 체크 여부에 따라서 값이 초기화되어 전체 체크의 대한 상태 값 을 갖게 된다. 다음으로 체크 박스 구현한 부분을 살펴보면 sample 리스트를 forEachIndexed문으로 Che...

Compose radio button - size, padding 변경

이미지
라디오 버튼 라디오 버튼은 사용자가 여러 옵션 중 하나를 선택할 수 있게 하는 UI 중 하나 이다. 옵션들이 직관적으로 나타나기 때문에 사용자가 옵션을 간편하게 선택 가능 하지만 선택할 옵션이 많은 경우에는 그만큼 공간을 많이 차지하기 때문에 적합하지 않을 수 있다. 그림1. Radio Button 라디오 버튼 구현 먼저 변수 부분을 살펴보면  items는 라디오 버튼의 항목들이며 selectedItem은 라디오 버튼 선택 시 옵션을 저장할 변수이다. 다음으로 RadioButton 부분을 보면 items를 forEach문을 사용하여 각 Row를 추가해주었다. 여기서 텍스트를 나타내기 위해 Text 컴포저블이 아닌 ClickableText 컴포저블을 사용하였는데 이는 텍스트를 클릭하였을 때도 옵션이 선택 되도록 하기 위함이다. @Composable fun Main (innerPadding: PaddingValues) { val items = listOf ( "Option 1" , "Option 2" , "Option 3" ) var selectedItem by remember { mutableStateOf ( "Option" ) } Column ( modifier = Modifier . padding (innerPadding) . fillMaxSize (), horizontalAlignment = Alignment. CenterHorizontally , verticalArrangement = Arrangement. Center ) { Text ( text = selectedItem, fontSize = 28 . sp ) Spacer ( modifier = Modifier. height ( 18 . dp )) items. forEach {...

Compose custom snackbar - 커스텀 토스트 메시지

이미지
SnackBar  스낵바는 화면 하단에 나타나 간단한 알림 역할을 한다. 잠깐 나타난 후 사라지므로, 사용자를 방해하지 않으면서도 사용자에게 변경 사항을 알려주거나 특정 작업의 실행 여부를 제시할 수도 있다. 그림1. Snackbar 이 스낵바가 경우에 따라서 커스텀 된 레이아웃으로 나타내고 싶을 때가 있는데  그럴 경우를 위해서 스낵바를 커스텀 하는 방법 을 알아보도록 하겠다. SnackBar 구현 스낵바를 구현하기 위해서 SnackbarHostState을 갖는 SnackbarHost를(변수명=snackBarHostState) 선언해준다. 이를 Scaffold 파라미터 중 하나인 snackbarHost서 호출한 SnackbarHost 의 hostState 값으로 초기화 해준다. 이후 SnackbarHost에서 직접 커스텀한 스낵바를 호출해주면 끝이다. 이 부분에서 추가적으로 알고 있으면 좋은 부분을 살펴보면 만약 Scaffold가 없다면 SnackbarHost를 다른 곳에 위치하여도 무관 하다. 대신 이 경우에는 스낵바가 나타날 위치를 조정해 줄 필요가 있다. 또한 modifier을 보면 offset을 사용하였는데, offset을 사용하여 스낵바가 나타날 위치를 조절 할 수 있어서 해당 예시에서는 y = -100 이기 때문에 본래 스낵바가 나타나는 것보다 더 위쪽에서 스낵바가 나타나는 것을 확인할 수 있다. @Composable fun Main () { val snackBarHostState = remember { SnackbarHostState() } val coroutineScope = rememberCoroutineScope () Scaffold ( modifier = Modifier. fillMaxSize (), snackbarHost = { SnackbarHost ( hostState = snackBarHostState, modifier = Mod...

Compose drawer menu - NavigationDrawer

이미지
Navigation Drawer Navigation Drawer란 Drawer(=서랍)처럼 열고 닫는 식으로 동작하는 네비게이션 메뉴이다. 보통 애플리케이션 왼쪽 최상단 위치하여, TopAppBar에서 열고 닫을 수 있는 메뉴로서 사용 된다. 그림1. topAppBar menu 닫힌 상태에서는 전혀 공간을 차지하기 않기 때문에 네비게이션 메뉴로 유용하게 사용할 수 있다. ModalNavigationDrawer Compose에서 navigation drawer 구현하기 위해서 ModalNavigationDrawer를 사용할 수 있다. ModalNavigationDrawer를 알아보기 전에 우선 사용되는 변수들을 살펴보면 val drawerState = rememberDrawerState ( initialValue = DrawerValue. Closed ) val scope = rememberCoroutineScope () val icons = listOf (Icons.Filled. Home , Icons.Filled. Person , Icons.Filled. Settings ) val sample = listOf ( "Home" , "Profile" , "Setting" ) var text by remember { mutableStateOf ( "" ) } drawerState : drawer 상태 변수. opne, close 같은 drawer의 대한 상태 값 을 갖는다. scope : navigation을 open 하거나 close 할 때 사용할 코루틴 scope icons : navigation 메뉴 아이콘 sample : navigation 메뉴 텍스트 text : 메뉴서 선택한 텍스트 여기서 drawerState 변수를 사용하여 navigation을 열고 닫는 동작을 제어 한다. 계속해서 ModalNavigationDrawer 사용하는 방법을 알아보자 ModalNavigationDra...

Compose 박스 메뉴 - DropdownMenuBox

이미지
DropdownMenuBox DropdownMenuBox는 사용자가 옵션을 선택하도록 하는 UI 중 많이 사용하는 것 중 하나 이다. 그림1. DropdownMenuBox 기본적으로 접혀 있다가 선택 시에만 펼쳐 서 옵션들을 나타내기 때문에 많은 옵션들을 담을 수 있으며, 공간을 덜 낭비 하게 된다. 선택해야 할 옵션이 많지 않으면 굳이 사용할 필요는 없지만  공간을 덜 낭비하고, DropdownMenuBox를 사용하면 여기서 무엇을 위하여 선택하는 것이 명확히 알 수 있어서 경우에 따라서 유용하게 사용할 수 있다. ExposedDropdownMenuBox 사용 Compose에서 DropdownMenuBox를 구현하기 위해서는 ExposedDropdownMenuBox를 사용할 수 있다. ExposedDropdownMenuBox 구현을 알아보기 전 먼저 여기서 사용할 각 변수들을 먼저 살펴보면 val sample = listOf ( "item01" , "item02" , "item03" , "item04" ) var text by remember { mutableStateOf ( "" ) } var expanded by remember { mutableStateOf ( false ) } sample : 메뉴 박스서 보여줄 선택 옵션들 text : 옵션 선택 시 해당 옵션 값 지정. 특정한 값에 대한 선택이면 이런 식으로 값을 저장할 수도 있으며, 옵션에 따른 결과가 동작일 경우에는 각 Click 이벤트를 구현하면 된다. expanded : 메뉴 박스가 나타날지 감춰질지 여부 앞서 ExposedDropdownMenuBox서 사용할 변수들을 알아 봤으니 계속해서 ExposedDropdownMenuBox를 사용하는 것을 보면 ExposedDropdownMenuBox 구현하기 위해서 OutlinedTextField와 ExposedDropdownMenu를 같이 사용 할 것이다. 왜냐...

Compose status bar transparent - 상태 바 색 변경

이미지
상태 바 색 변경 Compose에서 상태 바 색을 변경하기 위해서는 Theme.kt 파일에서 코드 몇 줄을 추가해 주면 된다. Theme.kt 파일을 보면 프로젝트 명에 따라서 "<프로젝트 명>Theme" 함수가 있는데, 그 함수에서 아래 코드를 추가 해 주면 된다. val view = LocalView . current if (!view. isInEditMode ) { SideEffect { val window = (view. context as Activity). window window. statusBarColor = Color ( 255 , 194 , 71 , 255 ). toArgb () window. navigationBarColor = Color ( 255 , 194 , 71 , 255 ). toArgb () WindowCompat.getInsetsController(window, view). isAppearanceLightStatusBars = !darkTheme } } 여기서  window. statusBarColor  부분이 상태 바의 색을 지정하는 부분 으로 위처럼 특정 색을 지정해 줄 수 있다. 혹은  Color. Transparent 로 색을 지정하거나  colorScheme. primary 를 사용하여 애플리케이션에서 정의된 색으로 색을 지정할 수 있다. 이중에는 Light/Dark 테마에 따라서 그에 맞는 상태 창 색을 지정하거나 해당 애플리케이션의 퍼스널 컬러를 지정하므로 주로 colorScheme의 있는 색으로 지정하곤 한다. 그림1. statusBarColor 다음으로  window. navigationBarColor  부분은 화면 아랫부분에 위치한 네비게이션 바의 색을 지정 한다. 이는 기종에 따라서 다르게 나타나지만, 의도한 대로 화면이 나타나게 하고 싶으면 이 부분도 설정해주는 것이...

Compose 숫자 선택 - NumberPicker

이미지
NumberPicker NumberPicker는 사용자가 숫자를 선택하도록 하여 입력 받는 방법이다. 스크롤로 숫자를 선택하여 사용자가 편하게 숫자를 입력할 수 있도록 할 수 있지만 숫자를 그대로 입력 받도록 구현하면 되기 때문에 반드시 필요한 요소도 아니다. 그림1. NumberPicker 그렇지만 날짜와 같이 어느 정도 선택 범위가 정해져 있는 년, 월, 일이나 시간 같은 값 을 입력 받아야 할 때 사용자에게 제한된 범위를 제한하여 입력 받을 수 있는 NumberPicker가 더욱 높은 사용성을 제공 할 수 있다. 그러면 이제 이러한 경우에 활용할 수 있는 NumberPicker는 구현하는 방법을 알아보도록 하겠다. NumberPicker 구현 기존의 안드로이드에서는 NumberPicker를 구현하기 위한 방법을 제공하였지만 Compose에서는 NumberPicker 구현한 컴포저블이 정의되어 있지 않기 때문에 직접 구현해 줄 필요가 있다. 그렇기 때문에 구현하는 방법이 다양하게 있는데, 그 중 가장 간단한 방법은 기존의 NumberPicker와 AndroidView를 사용하는 방법 이다. AndroidView는 기존 안드로이드 뷰를 Compose에 통합 하는 데 사용하는 컴포저블 함수이다. 앞서 기존 안드로이드에서는 NumberPicker를 제공했었다 했는데 그러니 AndroidView를 사용하여 기존의 NumberPicker를 사용하면 간단하게 NumberPicker 구현 이 가능해진다. 추가적으로 Dialog와 함께 사용하여 값을 입력 받도록 하였다. 그림2. 실행 화면 @Composable fun MyNumberPicker ( context: Context, onDismissRequest: () -> Unit, onConfirmation: (Int) -> Unit, default: Int ) { val numberPicker = NumberPicker(context) numberPicker. mi...

Compose 대화상자 - AlertDialog, Dialog

이미지
AlertDialog, Dialog AlertDialog, Dialog 둘 다 팝업 메시지를 나타내기 위한 대화 상자를 만드는 컴포넌트이다. 팝업이 되어서 나타나기 때문에 사용자가 해당 메시지의 집중할 수 있도록 UI 구성이 가능하다. 그래서 사용자에게 작업을 확인 받아야 할 경우, 사용자에게 선택이나 입력을 요구하는 일이 있을 경우 주로 사용 된다. 그림1. 대화 상자 예시 그러면 이러한 대화 상자를 만들기 위해서 AlertDialog, Dialog 2가지를 사용할 수 있는데, 이 2 가지는 각각 용도와 기능적으로 몇 가지 차이점이 있다. 가장 큰 차이점을 말하면 Dialog는 레이아웃을 자유롭게 구성이 가능하고 AlertDialog는 제공하는 레이아웃에 따라 구성 해야 한다는 것이다. 상세한 차이들은 아래에서 알아보도록 하겠다. AlertDialog AlertDialog는 사용자가 결정을 내려야 하거나, 중요한 내용을 알리고자 할 경우 경고나 확인 취소 목적으로 사용한다. 그리고 AlertDialog는 제목, 텍스트, 취소/확인 버튼과 같이 이미 정의된 레이아웃 에서 각 값을 채워 넣을 수 있도록 되어 있다. 그렇기 때문에 동일한 레이아웃으로만 구성 가능하지만, 이는 달리 말하면 형식적인 레이아웃으로 간단하게 Dialog 구현할 수 있다는 장점 이 된다. 그림2. AlertDialog @Composable fun Dialog01 ( onDismissRequest: () -> Unit, onConfirmation: () -> Unit, dialogTitle: String, dialogText: String, ) { AlertDialog ( icon = { Icon (Icons. Default . Info , contentDescription = "" ) } , title = { Text ( text = dial...