Я использую Scaffold со столбцом, содержащим мои поля ввода и кнопки, заключенные в Modifier.verticalScroll(scrollState). Я использую собственный метод RememberImeState() для определения активности клавиатуры, а затем вызываю метод ScrollState.animateScrollTo(scrollState.maxValue) в LaunchedEffect.
Код ImeState:
Код: Выделить всё
@Composable
fun rememberImeState(): State {
val imeState = remember {
mutableStateOf(false)
}
val view = LocalView.current
DisposableEffect(view) {
val listener = ViewTreeObserver.OnGlobalLayoutListener {
val isKeyboardOpen = ViewCompat.getRootWindowInsets(view)
?.isVisible(WindowInsetsCompat.Type.ime()) ?: true
imeState.value = isKeyboardOpen
}
view.viewTreeObserver.addOnGlobalLayoutListener(listener)
onDispose {
view.viewTreeObserver.removeOnGlobalLayoutListener(listener)
}
}
return imeState
}
Код: Выделить всё
@Composable
fun Login() {
val imeState = rememberImeState()
val scrollState = rememberScrollState()
LaunchedEffect(key1 = imeState.value) {
if (imeState.value) {
scrollState.animateScrollTo(scrollState.maxValue, tween(300))
}
}
var email by remember {
mutableStateOf("")
}
var password by remember {
mutableStateOf("")
}
Scaffold(
topBar = {
// Top app bar with a back button and header text
TopAppBar(
title = {Text("Login")},
navigationIcon = {
IconButton(
onClick = {},
content = {
Icon(imageVector = Icons.AutoMirrored.Filled.ArrowBack,
contentDescription = null)
}
)
}
)
},
) { innerPadding ->
Column(
modifier = Modifier
.verticalScroll(scrollState)
.fillMaxSize()
.padding(innerPadding)
.padding(16.dp)
.focusable(),
verticalArrangement = Arrangement.Top,
horizontalAlignment = CenterHorizontally
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = "Email or Username",
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Start,
)
Spacer(modifier = Modifier.size(4.dp))
TextField(
value = email,
onValueChange = {
email = it
},
)
Spacer(modifier = Modifier.size(32.dp))
Text(
modifier = Modifier.fillMaxWidth(),
text = "Password",
style = MaterialTheme.typography.titleLarge,
textAlign = TextAlign.Start,
)
Spacer(modifier = Modifier.size(4.dp))
TextField(
value = password,
onValueChange = {
password = it
},
)
Spacer(modifier = Modifier.size(4.dp))
Text(
text = "errorMessage",
fontSize = 12.sp
)
Spacer(modifier = Modifier.height(25.dp))
Button(
modifier = Modifier.height(43.dp),
onClick = {},
content = {
Text("Login")
}
)
Spacer(modifier = Modifier.height(2.dp))
Button(modifier = Modifier.height(43.dp),
onClick = {},
content = {
Text("Log in without password")
}
)
}
}
}

Подробнее здесь: https://stackoverflow.com/questions/798 ... rd-appears