상황 : 회원가입 페이지 구현 중 TextField에 관한 UX적인 부분의 구현이 필요했다.
![]() | ![]() |
---|
fun Modifier.addFocusCleaner(focusManager: FocusManager, doOnClear: () -> Unit = {}): Modifier {
return this.pointerInput(Unit) {
detectTapGestures(onTap = {
doOnClear()
focusManager.clearFocus()
})
}
}
val focusManager = LocalFocusManager.current
@Composable
fun MainContent(
) {
Scaffold(
modifier = Modifier
.fillMaxSize()
.addFocusCleaner(focusManager)
) {
...
}
}
singleLine = true
로 만들면 키보드의 엔터키가 “완료”키로 바뀌어있는것을 확인할 수 있습니다.KeyboardActions
의 onDone
으로 구현이 가능하다.@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainTextField(
text: String = "",
onValueChange: (String) -> Unit,
focusManager: FocusManager
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth(),
label = { Text("입력") },
value = text,
onValueChange = onValueChange,
singleLine = true,
keyboardActions = KeyboardActions(onDone = {
focusManager.moveFocus(FocusDirection.Next)
})
)
}
package test.composestarter
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.gestures.detectTapGestures
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusManager
import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.unit.dp
import test.composestarter.ui.theme.ComposeStarterTheme
import test.composestarter.ui.theme.WhiteColor
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
ComposeStarterTheme {
MainScreen()
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainScreen() {
val focusManager = LocalFocusManager.current
Scaffold(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = 16.dp)
.background(WhiteColor)
.addFocusCleaner(focusManager),
) { paddingValues ->
paddingValues
var text1 by remember { mutableStateOf("") }
var text2 by remember { mutableStateOf("") }
var text3 by remember { mutableStateOf("") }
Column(
) {
MainTextField(
text = text1,
onValueChange = {
text1 = it
},
focusManager = focusManager
)
MainTextField(
text = text2,
onValueChange = {
text2 = it
},
focusManager = focusManager
)
MainTextField(
text = text3,
onValueChange = {
text3 = it
},
focusManager = focusManager
)
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MainTextField(
text: String = "",
onValueChange: (String) -> Unit,
focusManager: FocusManager
) {
OutlinedTextField(
modifier = Modifier
.fillMaxWidth(),
label = { Text("입력") },
value = text,
onValueChange = onValueChange,
singleLine = true,
keyboardActions = KeyboardActions(onDone = {
focusManager.moveFocus(FocusDirection.Next)
})
)
}
fun Modifier.addFocusCleaner(focusManager: FocusManager, doOnClear: () -> Unit = {}): Modifier {
return this.pointerInput(Unit) {
detectTapGestures(onTap = {
doOnClear()
focusManager.clearFocus()
})
}
}