From 2912bc92a2d325f0c8096e0f0e3eecc0604244d7 Mon Sep 17 00:00:00 2001 From: MohitMaliFtechiz Date: Thu, 28 Nov 2024 23:02:43 +0530 Subject: [PATCH] Fixed: Virtual keyboard resetting the search in the library. * The issue was with android 14 device, it is working fine in below devices. * Improved the back press handling in CoreMainActivity using the latest onBackPressedDispatcher API, ensuring proper functionality on Android 14 and above. * Enhanced the back press behavior in OnlineLibraryFragment while searching for ZIM files, so the SearchView does not close immediately when the user presses the back button to simply dismiss the keyboard. --- .../library/OnlineLibraryFragment.kt | 8 ++- core/src/main/AndroidManifest.xml | 1 - .../core/extensions/FragmentExtensions.kt | 7 +++ .../kiwixmobile/core/main/CoreMainActivity.kt | 54 ++++++++++++------- 4 files changed, 48 insertions(+), 22 deletions(-) diff --git a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt index 513d5b651..b0f8ecc39 100644 --- a/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt +++ b/app/src/main/java/org/kiwix/kiwixmobile/nav/destination/library/OnlineLibraryFragment.kt @@ -68,6 +68,7 @@ import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.requestNotificat import org.kiwix.kiwixmobile.core.extensions.ActivityExtensions.viewModel import org.kiwix.kiwixmobile.core.extensions.closeKeyboard import org.kiwix.kiwixmobile.core.extensions.coreMainActivity +import org.kiwix.kiwixmobile.core.extensions.isKeyboardVisible import org.kiwix.kiwixmobile.core.extensions.setBottomMarginToFragmentContainerView import org.kiwix.kiwixmobile.core.extensions.setUpSearchView import org.kiwix.kiwixmobile.core.extensions.snack @@ -327,8 +328,11 @@ class OnlineLibraryFragment : BaseFragment(), FragmentActivityExtensions { } override fun onBackPressed(activity: AppCompatActivity): FragmentActivityExtensions.Super { - getActivity()?.finish() - return FragmentActivityExtensions.Super.ShouldNotCall + if (isKeyboardVisible()) { + closeKeyboard() + return FragmentActivityExtensions.Super.ShouldNotCall + } + return FragmentActivityExtensions.Super.ShouldCall } private fun onRefreshStateChange(isRefreshing: Boolean?) { diff --git a/core/src/main/AndroidManifest.xml b/core/src/main/AndroidManifest.xml index 0f01dfdc6..1a5bdc0a3 100644 --- a/core/src/main/AndroidManifest.xml +++ b/core/src/main/AndroidManifest.xml @@ -55,7 +55,6 @@ android:fullBackupContent="@xml/backup_rules" android:dataExtractionRules = "@xml/data_extraction_rules" android:hardwareAccelerated="true" - android:enableOnBackInvokedCallback="true" android:largeHeap="true" android:requestLegacyExternalStorage="true" android:resizeableActivity="true" diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt index 4a37ed58b..2f7dd640c 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/extensions/FragmentExtensions.kt @@ -22,6 +22,8 @@ import android.content.Context import android.view.View import android.view.inputmethod.InputMethodManager import android.widget.Toast +import androidx.core.view.ViewCompat +import androidx.core.view.WindowInsetsCompat import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -36,6 +38,11 @@ fun Fragment.toast(stringId: Int, length: Int = Toast.LENGTH_LONG) { requireActivity().toast(stringId, length) } +fun Fragment.isKeyboardVisible(): Boolean { + val insets = ViewCompat.getRootWindowInsets(requireView()) ?: return false + return insets.isVisible(WindowInsetsCompat.Type.ime()) +} + fun Fragment.closeKeyboard() { val inputMethodManager = requireContext().getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager diff --git a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt index 27d016fee..9b65ff19e 100644 --- a/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt +++ b/core/src/main/java/org/kiwix/kiwixmobile/core/main/CoreMainActivity.kt @@ -24,6 +24,7 @@ import android.os.Process import android.view.ActionMode import android.view.Menu import android.view.MenuItem +import androidx.activity.OnBackPressedCallback import androidx.appcompat.app.ActionBarDrawerToggle import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.widget.Toolbar @@ -47,6 +48,7 @@ import org.kiwix.kiwixmobile.core.CoreApp import org.kiwix.kiwixmobile.core.R import org.kiwix.kiwixmobile.core.base.BaseActivity import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions +import org.kiwix.kiwixmobile.core.base.FragmentActivityExtensions.Super.ShouldCall import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToLibkiwixMigrator import org.kiwix.kiwixmobile.core.data.remote.ObjectBoxToRoomMigrator import org.kiwix.kiwixmobile.core.di.components.CoreActivityComponent @@ -132,6 +134,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { } downloadManagerBroadcastReceiver.let(::registerReceiver) createApplicationShortcuts() + handleBackPressed() } @Suppress("DEPRECATION") @@ -149,6 +152,7 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { } override fun onDestroy() { + onBackPressedCallBack.remove() downloadManagerBroadcastReceiver.let(::unregisterReceiver) super.onDestroy() } @@ -277,28 +281,40 @@ abstract class CoreMainActivity : BaseActivity(), WebViewProvider { externalLinkOpener.openExternalUrl(KIWIX_SUPPORT_URL.toUri().browserIntent()) } - override fun onBackPressed() { - if (navigationDrawerIsOpen()) { - closeNavigationDrawer() - return - } - if (activeFragments().filterIsInstance().isEmpty()) { - return super.onBackPressedDispatcher.onBackPressed() - } - activeFragments().filterIsInstance().forEach { - if (it.onBackPressed(this) == FragmentActivityExtensions.Super.ShouldCall) { - if (navController.currentDestination?.id?.equals(readerFragmentResId) == true && - navController.previousBackStackEntry?.destination - ?.id?.equals(searchFragmentResId) == false - ) { - drawerToggle = null - finish() - } else { - super.onBackPressedDispatcher.onBackPressed() + private fun handleBackPressed() { + onBackPressedDispatcher.addCallback(this, onBackPressedCallBack) + } + + private val onBackPressedCallBack = + object : OnBackPressedCallback(true) { + override fun handleOnBackPressed() { + if (navigationDrawerIsOpen()) { + closeNavigationDrawer() + return + } + if (activeFragments().filterIsInstance().isEmpty()) { + isEnabled = false + return onBackPressedDispatcher.onBackPressed().also { + isEnabled = true + } + } + activeFragments().filterIsInstance().forEach { + if (it.onBackPressed(this@CoreMainActivity) == ShouldCall) { + if (navController.currentDestination?.id?.equals(readerFragmentResId) == true && + navController.previousBackStackEntry?.destination + ?.id?.equals(searchFragmentResId) == false + ) { + drawerToggle = null + finish() + } else { + isEnabled = false + onBackPressedDispatcher.onBackPressed() + isEnabled = true + } + } } } } - } override fun onCreateOptionsMenu(menu: Menu): Boolean {