Improve keyboard behavior

- Hide keyboard on pause
- Show keyboard on resume if search is open and auto focus is enabled

Fix #40
This commit is contained in:
MM20 2022-03-13 13:10:20 +01:00
parent a20707fc3c
commit 6b69d79f85
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 38 additions and 9 deletions

View File

@ -20,6 +20,9 @@ import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import androidx.core.view.WindowInsetsControllerCompat import androidx.core.view.WindowInsetsControllerCompat
import androidx.core.view.setPadding import androidx.core.view.setPadding
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import de.mm20.launcher2.ktx.dp import de.mm20.launcher2.ktx.dp
import de.mm20.launcher2.ktx.isAtLeastApiLevel import de.mm20.launcher2.ktx.isAtLeastApiLevel
import de.mm20.launcher2.transition.OneShotLayoutTransition import de.mm20.launcher2.transition.OneShotLayoutTransition
@ -28,6 +31,8 @@ import de.mm20.launcher2.ui.databinding.ViewLauncherScaffoldBinding
import de.mm20.launcher2.ui.launcher.search.SearchBarVM import de.mm20.launcher2.ui.launcher.search.SearchBarVM
import de.mm20.launcher2.ui.launcher.search.SearchVM import de.mm20.launcher2.ui.launcher.search.SearchVM
import de.mm20.launcher2.ui.launcher.widgets.WidgetsVM import de.mm20.launcher2.ui.launcher.widgets.WidgetsVM
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.launch
@SuppressLint("ClickableViewAccessibility") @SuppressLint("ClickableViewAccessibility")
class LauncherScaffoldView @JvmOverloads constructor( class LauncherScaffoldView @JvmOverloads constructor(
@ -107,6 +112,19 @@ class LauncherScaffoldView @JvmOverloads constructor(
ObjectAnimator.ofInt(binding.scrollView, "scrollY", 0).setDuration(200).start() ObjectAnimator.ofInt(binding.scrollView, "scrollY", 0).setDuration(200).start()
} }
context.lifecycleScope.launch {
context.lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
if (viewModel.isSearchOpen.value == true && autoFocus) {
searchBarViewModel.setFocused(true)
}
try {
awaitCancellation()
} finally {
searchBarViewModel.setFocused(false)
}
}
}
binding.scrollView.scrollY = viewModel.scrollY binding.scrollView.scrollY = viewModel.scrollY
binding.scrollView.setOnTouchListener(scrollViewOnTouchListener) binding.scrollView.setOnTouchListener(scrollViewOnTouchListener)

View File

@ -32,8 +32,11 @@ import androidx.compose.ui.focus.onFocusChanged
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.repeatOnLifecycle
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import coil.compose.rememberImagePainter import coil.compose.rememberImagePainter
import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.ktx.tryStartActivity
@ -45,19 +48,32 @@ import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.launcher.LauncherActivityVM import de.mm20.launcher2.ui.launcher.LauncherActivityVM
import de.mm20.launcher2.ui.locals.LocalCardStyle import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.settings.SettingsActivity import de.mm20.launcher2.ui.settings.SettingsActivity
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
import org.koin.androidx.compose.inject import org.koin.androidx.compose.inject
import java.io.File import java.io.File
@Composable @Composable
fun SearchBar( fun SearchBar(
level: SearchBarLevel, level: SearchBarLevel
onFocus: () -> Unit = {}
) { ) {
val searchViewModel: SearchVM = viewModel() val searchViewModel: SearchVM = viewModel()
val activityViewModel: LauncherActivityVM = viewModel() val activityViewModel: LauncherActivityVM = viewModel()
val viewModel: SearchBarVM = viewModel() val viewModel: SearchBarVM = viewModel()
val lifecycle = LocalLifecycleOwner.current.lifecycle
LaunchedEffect(null) {
lifecycle.repeatOnLifecycle(Lifecycle.State.RESUMED) {
try {
awaitCancellation()
} finally {
viewModel.setFocused(false)
}
}
}
val dataStore: LauncherDataStore by inject() val dataStore: LauncherDataStore by inject()
val style by remember { dataStore.data.map { it.searchBar.searchBarStyle } } val style by remember { dataStore.data.map { it.searchBar.searchBarStyle } }

View File

@ -16,8 +16,6 @@ import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.ui.MdcLauncherTheme import de.mm20.launcher2.ui.MdcLauncherTheme
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.launcher.search.SearchBar
import de.mm20.launcher2.ui.launcher.search.SearchBarLevel
import de.mm20.launcher2.ui.locals.LocalCardStyle import de.mm20.launcher2.ui.locals.LocalCardStyle
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.map
@ -27,7 +25,7 @@ import org.koin.core.component.inject
class SearchBarView @JvmOverloads constructor( class SearchBarView @JvmOverloads constructor(
context: Context, context: Context,
attrs: AttributeSet? = null, attrs: AttributeSet? = null,
defStyleAttr: Int = R.attr.materialCardViewStyle defStyleAttr: Int = 0
) : FrameLayout(context, attrs, defStyleAttr), KoinComponent { ) : FrameLayout(context, attrs, defStyleAttr), KoinComponent {
var level: SearchBarLevel = SearchBarLevel.Resting var level: SearchBarLevel = SearchBarLevel.Resting
@ -39,8 +37,6 @@ class SearchBarView @JvmOverloads constructor(
private val dataStore: LauncherDataStore by inject() private val dataStore: LauncherDataStore by inject()
private val levelState = MutableLiveData(level) private val levelState = MutableLiveData(level)
var onFocus: (() -> Unit)? = null
init { init {
val view = ComposeView(context) val view = ComposeView(context)
view.setContent { view.setContent {
@ -56,8 +52,7 @@ class SearchBarView @JvmOverloads constructor(
MdcLauncherTheme { MdcLauncherTheme {
Box(contentAlignment = Alignment.TopCenter) { Box(contentAlignment = Alignment.TopCenter) {
SearchBar( SearchBar(
level, level
onFocus = { onFocus?.invoke() }
) )
} }
} }