SearchToolbar: Better physical keyboard support (#8529)
Make enter keys behave like search key of on-screen keyboard
This commit is contained in:
parent
c31cf2a03a
commit
acd43005df
@ -44,6 +44,7 @@ import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import eu.kanade.presentation.util.runOnEnterKeyPressed
|
||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||
import eu.kanade.tachiyomi.R
|
||||
|
||||
@ -251,25 +252,26 @@ fun SearchToolbar(
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusManager = LocalFocusManager.current
|
||||
|
||||
val searchAndClearFocus: () -> Unit = {
|
||||
onSearch(searchQuery)
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
}
|
||||
|
||||
BasicTextField(
|
||||
value = searchQuery,
|
||||
onValueChange = onChangeSearchQuery,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
.focusRequester(focusRequester)
|
||||
.runOnEnterKeyPressed(action = searchAndClearFocus),
|
||||
textStyle = MaterialTheme.typography.titleMedium.copy(
|
||||
color = MaterialTheme.colorScheme.onBackground,
|
||||
fontWeight = FontWeight.Normal,
|
||||
fontSize = 18.sp,
|
||||
),
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
keyboardActions = KeyboardActions(
|
||||
onSearch = {
|
||||
onSearch(searchQuery)
|
||||
focusManager.clearFocus()
|
||||
keyboardController?.hide()
|
||||
},
|
||||
),
|
||||
keyboardActions = KeyboardActions(onSearch = { searchAndClearFocus() }),
|
||||
singleLine = true,
|
||||
cursorBrush = SolidColor(MaterialTheme.colorScheme.onBackground),
|
||||
visualTransformation = visualTransformation,
|
||||
|
@ -62,6 +62,7 @@ import eu.kanade.presentation.components.LoadingScreen
|
||||
import eu.kanade.presentation.components.MangaCover
|
||||
import eu.kanade.presentation.components.ScrollbarLazyColumn
|
||||
import eu.kanade.presentation.util.plus
|
||||
import eu.kanade.presentation.util.runOnEnterKeyPressed
|
||||
import eu.kanade.presentation.util.secondaryItemAlpha
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||
@ -80,6 +81,10 @@ fun TrackServiceSearch(
|
||||
) {
|
||||
val focusManager = LocalFocusManager.current
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val dispatchQueryAndClearFocus: () -> Unit = {
|
||||
onDispatchQuery()
|
||||
focusManager.clearFocus()
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
contentWindowInsets = WindowInsets(
|
||||
@ -106,12 +111,13 @@ fun TrackServiceSearch(
|
||||
onValueChange = onQueryChange,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
.focusRequester(focusRequester)
|
||||
.runOnEnterKeyPressed(action = dispatchQueryAndClearFocus),
|
||||
textStyle = MaterialTheme.typography.bodyLarge
|
||||
.copy(color = MaterialTheme.colorScheme.onSurface),
|
||||
singleLine = true,
|
||||
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
|
||||
keyboardActions = KeyboardActions(onSearch = { focusManager.clearFocus(); onDispatchQuery() }),
|
||||
keyboardActions = KeyboardActions(onSearch = { dispatchQueryAndClearFocus() }),
|
||||
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
|
||||
decorationBox = {
|
||||
if (query.text.isEmpty()) {
|
||||
|
@ -54,6 +54,7 @@ import eu.kanade.presentation.components.Divider
|
||||
import eu.kanade.presentation.components.EmptyScreen
|
||||
import eu.kanade.presentation.components.Scaffold
|
||||
import eu.kanade.presentation.more.settings.Preference
|
||||
import eu.kanade.presentation.util.runOnEnterKeyPressed
|
||||
import eu.kanade.tachiyomi.R
|
||||
import eu.kanade.tachiyomi.util.system.isLTR
|
||||
|
||||
@ -108,7 +109,8 @@ class SettingsSearchScreen : Screen {
|
||||
onValueChange = { textFieldValue = it },
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusRequester(focusRequester),
|
||||
.focusRequester(focusRequester)
|
||||
.runOnEnterKeyPressed(action = focusManager::clearFocus),
|
||||
textStyle = MaterialTheme.typography.bodyLarge
|
||||
.copy(color = MaterialTheme.colorScheme.onSurface),
|
||||
singleLine = true,
|
||||
|
@ -10,6 +10,9 @@ import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.composed
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.input.key.Key
|
||||
import androidx.compose.ui.input.key.key
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
import androidx.compose.ui.layout.LayoutModifier
|
||||
import androidx.compose.ui.layout.Measurable
|
||||
import androidx.compose.ui.layout.MeasureResult
|
||||
@ -43,6 +46,22 @@ fun Modifier.clickableNoIndication(
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* For TextField, the provided [action] will be invoked when
|
||||
* physical enter key is pressed.
|
||||
*
|
||||
* Naturally, the TextField should be set to single line only.
|
||||
*/
|
||||
fun Modifier.runOnEnterKeyPressed(action: () -> Unit): Modifier = this.onPreviewKeyEvent {
|
||||
when (it.key) {
|
||||
Key.Enter, Key.NumPadEnter -> {
|
||||
action()
|
||||
true
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("ModifierInspectorInfo")
|
||||
fun Modifier.minimumTouchTargetSize(): Modifier = composed(
|
||||
inspectorInfo = debugInspectorInfo {
|
||||
|
Loading…
Reference in New Issue
Block a user