I'm having a small problem with my implementation of this tutorial:
I'm trying to position a Column
to the bottom of the entire screen, and then when a text field is focused, I want the Column
to rise above the keyboard.
I have achieved the following with this code:
@OptIn(ExperimentalFoundationApi::class, ExperimentalLayoutApi::class)
@ExperimentalComposeUiApi
fun Modifier.bringIntoViewAfterImeAnimation(): Modifier = composed {
var focusState by remember { mutableStateOf<FocusState?>(null) }
val relocationRequester = remember { BringIntoViewRequester() }
val isImeVisible = WindowInsets.isImeVisible
LaunchedEffect(
isImeVisible,
focusState,
relocationRequester
) {
if (isImeVisible && focusState?.isFocused == false) {
relocationRequester.bringIntoView()
}
relocationRequester.bringIntoView()
}
bringIntoViewRequester(relocationRequester).onFocusChanged { focusState = it }
}
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun SpaceCreator() {
val localFocusManager = LocalFocusManager.current
Column(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.Bottom
) {
Column(
modifier = Modifier.bringIntoViewAfterImeAnimation()
.background(color = Color.Gray.copy(alpha = 0.2f))
) {
Text(
modifier = Modifier.fillMaxWidth()
.background(color = Color.Yellow.copy(alpha = 0.5f)),
text = "Top Text",
style = MaterialTheme.typography.h2
)
Text(text = "Content", style = MaterialTheme.typography.h2)
OutlinedTextField(
value = "ss",
onValueChange = { },
label = { Text("Email Address") },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Done,
),
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
)
)
OutlinedTextField(
value = "ss",
onValueChange = { },
label = { Text("Email Address") },
singleLine = true,
modifier = Modifier.fillMaxWidth(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
)
)
Text(text = "Content", style = MaterialTheme.typography.h2)
}
}
}
And when I tap on the first, or second text field, I get this desired result:
However, when I tap on another text field, and the focus changes, the Column
repositions again, like so:
And the content of the Column
moves under the keyboard.
I'm getting it's because the animation is occurring on the event of a focus change, but I only want it to happen if the IME is not active, and then I want everything to stay the same.
I'm not quite sure what to do, but I've only gotten as far as to change the text fields' keyboard actions to:
imeAction = ImeAction.Done
and
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
)
But the user can still tap on another text field, which I need them to do, so this will break the usability. How can I fix this?
Any help would be appreciated, thank you and let me know if I can offer any more information.