From 6b69d79f8540d9cd3aec304547c9dc387025ed44 Mon Sep 17 00:00:00 2001 From: MM20 <15646950+MM2-0@users.noreply.github.com> Date: Sun, 13 Mar 2022 13:10:20 +0100 Subject: [PATCH] Improve keyboard behavior - Hide keyboard on pause - Show keyboard on resume if search is open and auto focus is enabled Fix #40 --- .../ui/launcher/LauncherScaffoldView.kt | 18 +++++++++++++++++ .../launcher2/ui/launcher/search/SearchBar.kt | 20 +++++++++++++++++-- .../ui/launcher/search/SearchBarView.kt | 9 ++------- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldView.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldView.kt index dbabdb36..f7439de5 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldView.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/LauncherScaffoldView.kt @@ -20,6 +20,9 @@ import androidx.core.content.ContextCompat import androidx.core.content.getSystemService import androidx.core.view.WindowInsetsControllerCompat 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.isAtLeastApiLevel 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.SearchVM import de.mm20.launcher2.ui.launcher.widgets.WidgetsVM +import kotlinx.coroutines.awaitCancellation +import kotlinx.coroutines.launch @SuppressLint("ClickableViewAccessibility") class LauncherScaffoldView @JvmOverloads constructor( @@ -107,6 +112,19 @@ class LauncherScaffoldView @JvmOverloads constructor( 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.setOnTouchListener(scrollViewOnTouchListener) diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBar.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBar.kt index 1ce7e0e7..ef8b1ba8 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBar.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBar.kt @@ -32,8 +32,11 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.lifecycle.Lifecycle +import androidx.lifecycle.repeatOnLifecycle import androidx.lifecycle.viewmodel.compose.viewModel import coil.compose.rememberImagePainter 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.locals.LocalCardStyle import de.mm20.launcher2.ui.settings.SettingsActivity +import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.flow.map import org.koin.androidx.compose.inject import java.io.File @Composable fun SearchBar( - level: SearchBarLevel, - onFocus: () -> Unit = {} + level: SearchBarLevel ) { val searchViewModel: SearchVM = viewModel() val activityViewModel: LauncherActivityVM = 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 style by remember { dataStore.data.map { it.searchBar.searchBarStyle } } diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBarView.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBarView.kt index e882ee3d..71837a9e 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBarView.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/SearchBarView.kt @@ -16,8 +16,6 @@ import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.Settings import de.mm20.launcher2.ui.MdcLauncherTheme 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 kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map @@ -27,7 +25,7 @@ import org.koin.core.component.inject class SearchBarView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, - defStyleAttr: Int = R.attr.materialCardViewStyle + defStyleAttr: Int = 0 ) : FrameLayout(context, attrs, defStyleAttr), KoinComponent { var level: SearchBarLevel = SearchBarLevel.Resting @@ -39,8 +37,6 @@ class SearchBarView @JvmOverloads constructor( private val dataStore: LauncherDataStore by inject() private val levelState = MutableLiveData(level) - var onFocus: (() -> Unit)? = null - init { val view = ComposeView(context) view.setContent { @@ -56,8 +52,7 @@ class SearchBarView @JvmOverloads constructor( MdcLauncherTheme { Box(contentAlignment = Alignment.TopCenter) { SearchBar( - level, - onFocus = { onFocus?.invoke() } + level ) } }