상세 컨텐츠

본문 제목

안드로이드/Android 의 (Compose) - 데이터 선택 가능한 피커 만들기 (Picker)

Android 자료실/기능 개발

by Victorywskim 2024. 1. 7. 17:54

본문

반응형

 

안드로이드 개발을 하다보면 데이터를 선택하는 여러가지 방법이 있습니다.

 

그 중에서 피커(Picker) 를 사용해서 데이터를 선택하는 방법을 알아보겠습니다.

 

구성 방법

 

  • 텍스트 데이터만 선택 할 수 있습니다.
  • 텍스트 데이터는 리스트 형태로 구성되어 있으며, 무한 스크롤이 가능합니다.
  • 선택되어 있는 텍스트 데이터가 무엇인지 알 수 있으며, 버튼 클릭 시 선택 값을 반환합니다.

 

아이템 목록 만들기

 

@Composable
fun InfiniteItemsSectionPicker(
    items: List<String>,
    firstIndex: Int,
    onItemSelected: (String) -> Unit,
) {

    val listState = rememberLazyListState(firstIndex)
    val currentValue = remember { mutableStateOf("") }
    val firstVisibleItemIndex by remember { derivedStateOf { listState.firstVisibleItemIndex } }

    LaunchedEffect(key1 = !listState.isScrollInProgress) {
        onItemSelected(currentValue.value)
        listState.animateScrollToItem(index = listState.firstVisibleItemIndex)
    }

    LazyColumn(
        horizontalAlignment = Alignment.CenterHorizontally,
        state = listState,
        modifier = Modifier.padding(start = 14.dp, end = 14.dp),
        content = {
            items(count = Int.MAX_VALUE, itemContent = {
                val modifierDivider = Modifier.fillMaxWidth()
                val index = it % items.size
                if (it == firstVisibleItemIndex + 2) {
                    currentValue.value = items[index]
                }

                if (it == firstVisibleItemIndex + 2) {
                    Divider(thickness = 2.dp, color = BlueA50, modifier = modifierDivider)
                }
                Spacer(modifier = Modifier.height(13.dp))
                TextMedium19(
                    text = items[index],
                    modifier = Modifier.alpha(if (it == firstVisibleItemIndex + 2) 1f else 0.3f).width(54.dp),
                    textColor = if (it == firstVisibleItemIndex + 2) Blue700 else Black,
                    textAlign = TextAlign.Center,
                    textScale = 1.1f
                )
                Spacer(modifier = Modifier.height(13.dp))
                if (it == firstVisibleItemIndex + 2) {
                    Divider(thickness = 2.dp, color = BlueA50, modifier = modifierDivider)
                }
            })
        }
    )
}

 

 

레이아웃 만들기

 

@Composable
fun DataSelectionSection(
    itemList: ArrayList<String>,
    resultData: (String) -> Unit,
) {
    Row(
        modifier = Modifier
            .fillMaxWidth()
            .height(280.dp),
        horizontalArrangement = Arrangement.Center
    ) {

        InfiniteItemsSectionPicker(
            items = itemList,
            firstIndex = (Int.MAX_VALUE / 2) - ((itemList.size % 2) - 1),
            onItemSelected = resultData
        )
    }
}

 

 

피커 구성하기

 

@Composable
fun DataPicker(
    label: String = "",
    itemList: ArrayList<String>,
    resultData: (date: String) -> Unit
) {
    Column(
        horizontalAlignment = Alignment.CenterHorizontally,
        modifier = Modifier
            .fillMaxWidth()
            .background(WHITE)
            .padding(vertical = 10.dp, horizontal = 5.dp)
            .animateContentSize()
    ) {
        if (label.isNotEmpty()) {
            Text(
                text = label,
                modifier = Modifier.fillMaxWidth(),
                textAlign = TextAlign.Center
            )

            Spacer(modifier = Modifier.height(30.dp))
        }

        val tempData = remember { mutableStateOf("") }

        DataSelectionSection(
            itemList = itemList,
            resultData = { tempData.value = it }
        )

        Spacer(modifier = Modifier.height(30.dp))

        FilledLargeButton(
            id = R.string.tcTagDatePickerSelectButton,
            text = stringResource(id = R.string.confirm),
            isEnable = remember { mutableStateOf(true) },
            clickAction = {
                resultData(tempData.value)
            }
        )
    }
}

 

 

테스트

 

@Preview(showBackground = true)
@Composable
fun DataPickerPreview() {
    val context = LocalContext.current
    DataPicker(
        label = "텍스트 선택 예제",
        itemList = arrayListOf("가","나","다","라","마","바")
    ) {
        Toast.makeText(context, "선택한 텍스트: $it", Toast.LENGTH_SHORT).show()
    }
}

 

 

동작하는 모습은 다음과 같습니다.

 

감사합니다.

 

 

 

 

 

 

 

728x90
반응형

관련글 더보기