본문 바로가기

Dev/안드로이드

Compose TextField 이용할 때 소프트 키보드와 포커스 처리하기

 

 혼자 진행 중인 프로젝트를 한참 만들어 나가다가, 오랜만에 사소하게나마 새로 알게 된 것이 생겼다. 프로젝트 내에서 TextField를 이용해 커스텀한 SearchBar composable을 만들게 되었는데, 막히는 부분이 생겼다.

 

 

 나는 위의 상태였던 SearchBar가 포커스를 얻으면(정확히는 처음 포커스를 얻는 순간이다) 아래의 형태로 바뀌어야 하고, 또 저 백버튼을 누르면 다시 위의 형태로 돌아가는 형태로 디자인을 하려고 했다.

 그 과정에서 몇몇 동작처리를 직접해주어야 했는데, 처음 포커스를 얻을 때 트리거 되는 부분은 TextField 내의 modifier에 clickable 값을 줘서 해결했지만 나머지가 문제였다.

 

 XML 및 바인딩 기반 View였다면, EditText 객체와 InputMethodManager를 이용해 평범하게 처리했을 것 같은데 Compose라서 방법이 바로 떠오르진 않았다.

FocusManager  |  Android Developers

 

FocusManager  |  Android Developers

androidx.compose.desktop.ui.tooling.preview

developer.android.com

SoftwareKeyboardController  |  Android Developers

 

SoftwareKeyboardController  |  Android Developers

androidx.compose.desktop.ui.tooling.preview

developer.android.com

 

 그래서 열심히 찾아보니 Compose에는 편한 내장 기능을 많이 제공하고 있었다.

@Composable
fun HomeTopBar(
    homeTopBarType: HomeTopBarType,
    modifier: Modifier = Modifier,
    onTextInputTriggered: () -> Unit = {},
    onBackArrowClicked: () -> Unit = {},
) {

    val textState = rememberSaveable { mutableStateOf("") }
    val focusManager = LocalFocusManager.current
    val keyboardController = LocalSoftwareKeyboardController.current

...

                            Icon(
                                imageVector = Icons.AutoMirrored.Filled.ArrowBack,
                                contentDescription = "back button",
                                modifier = Modifier.clickable {
                                    onBackArrowClicked()
                                    textState.value = ""
                                    focusManager.clearFocus()
                                    keyboardController?.hide()
                                }
                            )
...

 

 해당 객체들을 가져와서 Icon이 클릭되었을 때 FocusManager.clearFocus()와 SoftwareKeyboardController.hide()를 불러 처리했더니, 아래와 같이 의도대로 동작하는 것을 확인할 수 있었다. 

 

 

 근데 휴대폰 자체의 BackPressed 동작에도 같은 방식으로 대응해야해서, 추후에 조금 변경하게 될 것 같다.