Improve search keyboard dismissal (#317)

I need to test this more

Fixes the imeAction for search

Initiating the search will move focus down if results are available

Pressing back while focused on the search text box will move focus to
either the results or the nav drawer. I think will will help devices
that do not dismiss on the soft keyboard on back.

Might fix #311
This commit is contained in:
damontecres 2025-12-01 10:44:39 -05:00 committed by GitHub
parent d0bfdac3bd
commit fc330a3400
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 39 additions and 10 deletions

View file

@ -53,8 +53,8 @@ fun EditTextBox(
isInputValid: (String) -> Boolean = { true },
supportingText: @Composable (() -> Unit)? = null,
placeholder: @Composable (() -> Unit)? = null,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
) {
val interactionSource = remember { MutableInteractionSource() }
// From ButtonDefaults
val colors =
TextFieldDefaults.colors(
@ -157,6 +157,7 @@ fun SearchEditTextBox(
enabled: Boolean = true,
readOnly: Boolean = false,
height: Dp = 40.dp,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
) {
EditTextBox(
value,
@ -171,7 +172,7 @@ fun SearchEditTextBox(
KeyboardActions(
onSearch = {
onSearchClick.invoke()
this.defaultKeyboardAction(ImeAction.Done)
this.defaultKeyboardAction(ImeAction.Search)
},
),
leadingIcon = {
@ -181,9 +182,10 @@ fun SearchEditTextBox(
tint = MaterialTheme.colorScheme.onPrimaryContainer,
)
},
enabled,
readOnly,
height,
enabled = enabled,
readOnly = readOnly,
height = height,
interactionSource = interactionSource,
)
}

View file

@ -1,5 +1,9 @@
package com.github.damontecres.wholphin.ui.main
import androidx.activity.compose.BackHandler
import androidx.compose.foundation.focusGroup
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsFocusedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -18,10 +22,13 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.focus.FocusDirection
import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel
@ -157,6 +164,8 @@ fun SearchPage(
viewModel: SearchViewModel = hiltViewModel(),
) {
val context = LocalContext.current
val focusManager = LocalFocusManager.current
val keyboardController = LocalSoftwareKeyboardController.current
val movies by viewModel.movies.observeAsState(SearchResult.NoQuery)
val collections by viewModel.collections.observeAsState(SearchResult.NoQuery)
val series by viewModel.series.observeAsState(SearchResult.NoQuery)
@ -166,6 +175,7 @@ fun SearchPage(
val focusRequester = remember { FocusRequester() }
var position by rememberPosition()
var searchClicked by rememberSaveable { mutableStateOf(false) }
LaunchedEffect(query) {
delay(750L)
@ -177,17 +187,31 @@ fun SearchPage(
val onClickItem = { index: Int, item: BaseItem ->
viewModel.navigationManager.navigateTo(item.destination())
}
LaunchedEffect(searchClicked, movies, collections, series, episodes) {
if (searchClicked) {
if (listOf(movies, collections, series, episodes).any { it is SearchResult.Success }) {
focusManager.moveFocus(FocusDirection.Next)
searchClicked = false
}
}
}
LazyColumn(
contentPadding = PaddingValues(start = 16.dp, end = 16.dp, top = 16.dp, bottom = 44.dp),
verticalArrangement = Arrangement.spacedBy(16.dp),
modifier = modifier,
modifier = modifier.focusGroup(),
) {
item {
Box(
contentAlignment = Alignment.Center,
modifier = Modifier.fillMaxWidth(),
) {
val interactionSource = remember { MutableInteractionSource() }
val focused by interactionSource.collectIsFocusedAsState()
BackHandler(focused) {
keyboardController?.hide()
focusManager.moveFocus(FocusDirection.Next)
}
SearchEditTextBox(
value = query,
onValueChange = {
@ -195,12 +219,15 @@ fun SearchPage(
},
onSearchClick = {
viewModel.search(query)
searchClicked = true
},
modifier =
Modifier.ifElse(
position.row < MOVIE_ROW,
Modifier.focusRequester(focusRequester),
),
Modifier
.ifElse(
position.row < MOVIE_ROW,
Modifier.focusRequester(focusRequester),
),
interactionSource = interactionSource,
)
}
}