From 4732a67738aee969d4f2d34fb14013236a75e204 Mon Sep 17 00:00:00 2001 From: Kirill Nayduik Date: Fri, 2 Jul 2021 11:31:08 +0300 Subject: [PATCH] Add MviKeyboardResizableFragment --- mvi-arch/build.gradle | 1 + .../roboswag/mvi_arch/core/MviFragment.kt | 4 +- .../core/MviKeyboardResizableFragment.kt | 91 +++++++++++++++++++ 3 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviKeyboardResizableFragment.kt diff --git a/mvi-arch/build.gradle b/mvi-arch/build.gradle index 6059357..bfaa0aa 100644 --- a/mvi-arch/build.gradle +++ b/mvi-arch/build.gradle @@ -6,6 +6,7 @@ dependencies { implementation project(":lifecycle") implementation project(":kotlin-extensions") implementation project(":logging") + implementation project(":utils") implementation("androidx.core:core-ktx") implementation("androidx.appcompat:appcompat") diff --git a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt index 80e7758..37ea868 100644 --- a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt +++ b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviFragment.kt @@ -9,7 +9,6 @@ import androidx.annotation.LayoutRes import androidx.annotation.MainThread import androidx.core.os.bundleOf import androidx.fragment.app.Fragment -import androidx.fragment.app.FragmentActivity import androidx.lifecycle.Observer import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider @@ -18,6 +17,7 @@ import ru.touchin.roboswag.mvi_arch.di.ViewModelAssistedFactory import ru.touchin.roboswag.mvi_arch.di.ViewModelFactory import ru.touchin.roboswag.mvi_arch.marker.ViewAction import ru.touchin.roboswag.mvi_arch.marker.ViewState +import ru.touchin.roboswag.navigation_base.activities.BaseActivity import ru.touchin.roboswag.navigation_base.fragments.BaseFragment import ru.touchin.roboswag.navigation_base.fragments.EmptyState import javax.inject.Inject @@ -48,7 +48,7 @@ import javax.inject.Inject abstract class MviFragment( @LayoutRes layout: Int, navArgs: NavArgs = EmptyState as NavArgs -) : BaseFragment(layout) +) : BaseFragment(layout) where NavArgs : Parcelable, State : ViewState, Action : ViewAction, diff --git a/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviKeyboardResizableFragment.kt b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviKeyboardResizableFragment.kt new file mode 100644 index 0000000..4a6c55f --- /dev/null +++ b/mvi-arch/src/main/java/ru/touchin/roboswag/mvi_arch/core/MviKeyboardResizableFragment.kt @@ -0,0 +1,91 @@ +package ru.touchin.roboswag.mvi_arch.core + +import android.os.Bundle +import android.os.Parcelable +import android.view.View +import androidx.annotation.LayoutRes +import androidx.lifecycle.LifecycleObserver +import ru.touchin.roboswag.components.utils.hideSoftInput +import ru.touchin.roboswag.mvi_arch.marker.ViewAction +import ru.touchin.roboswag.mvi_arch.marker.ViewState +import ru.touchin.roboswag.navigation_base.activities.OnBackPressedListener +import ru.touchin.roboswag.navigation_base.keyboard_resizeable.KeyboardBehaviorDetector + +abstract class MviKeyboardResizableFragment( + @LayoutRes layout: Int +) : MviFragment(layout) + where NavArgs : Parcelable, + State : ViewState, + Action : ViewAction, + VM : MviViewModel { + + private var isKeyboardVisible: Boolean = false + + private val keyboardHideListener = OnBackPressedListener { + if (isKeyboardVisible) { + activity.hideSoftInput() + true + } else { + false + } + } + + private var isHideKeyboardOnBackEnabled = false + + protected open fun onKeyboardShow(diff: Int = 0) {} + + protected open fun onKeyboardHide() {} + + protected fun hideKeyboardOnBackPressed() { + isHideKeyboardOnBackEnabled = true + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + activity.keyboardBehaviorDetector = KeyboardBehaviorDetector(activity) + + view.requestApplyInsets() + lifecycle.addObserver(activity.keyboardBehaviorDetector as LifecycleObserver) + } + + override fun onResume() { + super.onResume() + if (isHideKeyboardOnBackEnabled) activity.addOnBackPressedListener(keyboardHideListener) + } + + override fun onPause() { + super.onPause() + notifyKeyboardHidden() + if (isHideKeyboardOnBackEnabled) activity.removeOnBackPressedListener(keyboardHideListener) + } + + override fun onStart() { + super.onStart() + activity.keyboardBehaviorDetector?.apply { + keyboardHideListener = { + if (isKeyboardVisible) { + onKeyboardHide() + } + isKeyboardVisible = false + } + keyboardShowListener = { diff -> + onKeyboardShow(diff) + isKeyboardVisible = true + } + } + } + + override fun onStop() { + super.onStop() + activity.keyboardBehaviorDetector?.apply { + keyboardHideListener = null + keyboardShowListener = null + } + } + + private fun notifyKeyboardHidden() { + if (isKeyboardVisible) onKeyboardHide() + isKeyboardVisible = false + } + +}