I have a problem, which I cannot solve ...
I have a activity where the user could add some information like name and so one. It is written in Kotlin with the Jetpack Compose library. One field is an AutoCompleteTextView where the systems gets information from a room database and display the stuff on a list below the textField. My problem is that this list is always shown behind the keyboard. (as show in the pictures below). How can I manage that the list is shown / scrolled into view? (the "InputFields" are located inside a scrollable column). When displaying the list above the textField then there is another problem: I lost the focus of the textField ...
My Code:
AutoCompleteView:
@Composable
fun <T> AutoCompleteTextView(
modifier: Modifier,
value: String,
label: String,
onValueChanged: (String) -> Unit = {},
predictions: List<T>,
clearVisible: Boolean = true,
keyBoardAction: ImeAction = ImeAction.Search,
onActionClick: () -> Unit = {},
onClearClick: () -> Unit = {},
onItemClick: (T) -> Unit = {},
itemContent: @Composable (T) -> Unit = {},
) {
val view = LocalView.current
val lazyListState = rememberLazyListState()
var showClearButton by remember { mutableStateOf(false) }
val focusRequester = remember { FocusRequester() }
LazyColumn(
state = lazyListState,
modifier = modifier.heightIn(max = TextFieldDefaults.MinHeight * 6)
) {
item {
OutlinedTextField(
modifier = modifier
.onFocusChanged { focusState ->
showClearButton = clearVisible and focusState.isFocused
}
.focusRequester(focusRequester),
value = value,
onValueChange = {
onValueChanged.invoke(it)
focusRequester.requestFocus()
},
label = { Text(text = label) },
singleLine = true,
trailingIcon = {
if (showClearButton) {
IconButton(painterResource(R.mipmap.ic_close),
stringResource(R.string.clear)) {
onClearClick()
}
}
},
keyboardActions = KeyboardActions(
onSearch = { onActionClick() },
onDone = { onActionClick() },
onGo = { onActionClick() },
onNext = { onActionClick() },
onPrevious = { onActionClick() },
onSend = { onActionClick() },
),
keyboardOptions = KeyboardOptions(
imeAction = keyBoardAction,
keyboardType = KeyboardType.Text
),
shape = RoundedCornerShape(10.dp),
colors = TextFieldDefaults.colors(
focusedIndicatorColor = MaterialTheme.colorScheme.primaryContainer,
unfocusedIndicatorColor =
MaterialTheme.colorScheme.secondaryContainer,
focusedContainerColor = Color.Transparent,
unfocusedContainerColor = Color.Transparent,
errorContainerColor = Color.Transparent
)
)
}
if (predictions.isNotEmpty()) {
itemsIndexed(predictions) { _, element ->
Row(
Modifier
.padding(5.dp)
.fillMaxWidth()
.clickable {
view.clearFocus()
onItemClick(element)
}
) {
itemContent(element)
}
}
}
}
}
Activity:
Box(
modifier = Modifier
.fillMaxWidth()
.padding(5.dp)
) {
Surface(
modifier = Modifier
.fillMaxWidth()
.padding(top = 10.dp),
shape = RoundedCornerShape(10.dp),
border = BorderStroke(1.dp,
MaterialTheme.colorScheme.secondaryContainer)
) {
Column {
Row(modifier = Modifier.wrapContentWidth()) {
Image(
modifier = Modifier
.verticalGradient()
.padding(start = 15.dp, top = 20.dp, end =
10.dp)
.size(24.dp),
painter = painterResource(R.mipmap.ic_dice),
contentDescription =
stringResource(R.string.genres)
)
Column(modifier = Modifier.wrapContentSize()) {
FlowRow(
modifier = Modifier
.wrapContentSize()
.padding(vertical = 6.dp),
horizontalArrangement =
Arrangement.spacedBy(5.dp, Start),
verticalArrangement = Arrangement.Top
) {
for (genre in genres) {
FilterChip(
modifier = Modifier.padding(horizontal
= 5.dp),
onClick = { genres.remove(genre) },
selected = true,
trailingIcon = {
Image(
modifier = Modifier
.verticalGradient()
.size(15.dp),
painter =
painterResource(R.mipmap.ic_close),
contentDescription =
stringResource(R.string.delete)
)
},
label = {
Text(genre.name)
}
)
}
}
Box(
Modifier
.fillMaxWidth()
.padding(horizontal = 10.dp)
.height(1.dp)
.background(MaterialTheme.colorScheme.secondaryContainer)
)
AutoCompleteTextView(modifier =
Modifier.padding(5.dp),
value = selectedGenreName,
label = "Genre",
onValueChanged = {
selectedGenreName = it
if (it.isNotEmpty()) {
getGenres(it)
} else {
filteredGenres.clear()
}
},
predictions = filteredGenres,
keyBoardAction = ImeAction.Done,
clearVisible = false,
onActionClick = {
val first = filteredGenres.stream().filter
{ it.name == selectedGenreName }.findFirst()
if (first.isPresent) {
genres.add(first.get())
} else {
genres.add(Genre().apply { name =
selectedGenreName })
}
selectedGenreName = ""
filteredGenres.clear()
},
onItemClick = {
genres.add(it)
selectedGenreName = ""
filteredGenres.clear()
}) {
Text(text = it.name)
}
}
}
}
}
Surface(
modifier = Modifier.padding(start = 15.dp),
color = MaterialTheme.colorScheme.background
) {
Text(
modifier = Modifier
.padding(horizontal = 5.dp)
.horizontalGradient(),
text = stringResource(R.string.genres),
fontSize = 14.sp
)
}
}



You can add this line
android:windowSoftInputMode="adjustResize"to the activity tag that holds this screen on the manifest file and the keyboard will push the screen up