add view controller which can detect keyboard opening
This commit is contained in:
parent
2296150667
commit
8e08c7a127
|
|
@ -22,6 +22,7 @@ package ru.touchin.roboswag.components.navigation.activities
|
|||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import ru.touchin.roboswag.components.navigation.keyboard_resizeable.KeyboardBehaviorDetector
|
||||
import ru.touchin.roboswag.components.navigation.viewcontrollers.LifecycleLoggingObserver
|
||||
import ru.touchin.roboswag.core.log.Lc
|
||||
import ru.touchin.roboswag.core.log.LcGroup
|
||||
|
|
@ -34,6 +35,8 @@ abstract class BaseActivity : AppCompatActivity() {
|
|||
|
||||
private val onBackPressedListeners = ArrayList<OnBackPressedListener>()
|
||||
|
||||
open val keyboardBehaviorDetector: KeyboardBehaviorDetector? = null
|
||||
|
||||
init {
|
||||
lifecycle.addObserver(LifecycleLoggingObserver())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
package ru.touchin.roboswag.components.navigation.keyboard_resizeable
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import ru.touchin.roboswag.components.navigation.activities.BaseActivity
|
||||
|
||||
// The workaround forces an activity to resize when keyboard appears in the full-screen mode
|
||||
class KeyboardBehaviorDetector(
|
||||
activity: BaseActivity,
|
||||
fragmentContainerId: Int
|
||||
) {
|
||||
|
||||
private val contentContainer = activity.findViewById(android.R.id.content) as ViewGroup
|
||||
private val fragmentContainer = activity.findViewById(fragmentContainerId) as ViewGroup
|
||||
private lateinit var rootView: View
|
||||
private val listener = { possiblyResizeChildOfContent() }
|
||||
|
||||
private var keyboardHideListener: (() -> Unit)? = null
|
||||
private var keyboardShowListener: ((Int) -> Unit)? = null
|
||||
|
||||
fun setKeyboardHideListener(listener: () -> Unit) {
|
||||
keyboardHideListener = listener
|
||||
}
|
||||
|
||||
fun removeKeyboardHideListener() {
|
||||
keyboardHideListener = null
|
||||
}
|
||||
|
||||
fun setKeyboardShowListener(listener: (Int) -> Unit) {
|
||||
keyboardShowListener = listener
|
||||
}
|
||||
|
||||
fun removeKeyboardShowListener() {
|
||||
keyboardShowListener = null
|
||||
}
|
||||
|
||||
// Call this in "onResume()" of a fragment
|
||||
fun startDetection() {
|
||||
|
||||
rootView = fragmentContainer.getChildAt(0)
|
||||
|
||||
contentContainer.viewTreeObserver.addOnGlobalLayoutListener(listener)
|
||||
}
|
||||
|
||||
// Call this in "onPause()" of a fragment
|
||||
fun stopDetection() {
|
||||
contentContainer.viewTreeObserver.removeOnGlobalLayoutListener(listener)
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/questions/2150078/how-to-check-visibility-of-software-keyboard-in-android?rq=1
|
||||
private fun possiblyResizeChildOfContent() {
|
||||
val rect = Rect()
|
||||
rootView.getWindowVisibleDisplayFrame(rect)
|
||||
val height = rootView.context.resources.displayMetrics.heightPixels
|
||||
val diff = height - rect.bottom
|
||||
|
||||
if (diff > rootView.rootView.height / 4) {
|
||||
keyboardShowListener?.invoke(diff)
|
||||
} else {
|
||||
keyboardHideListener?.invoke()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package ru.touchin.roboswag.components.navigation.keyboard_resizeable
|
||||
|
||||
import android.os.Build
|
||||
import android.os.Parcelable
|
||||
import androidx.annotation.LayoutRes
|
||||
import ru.touchin.roboswag.components.navigation.activities.BaseActivity
|
||||
import ru.touchin.roboswag.components.navigation.activities.OnBackPressedListener
|
||||
import ru.touchin.roboswag.components.navigation.viewcontrollers.ViewController
|
||||
import ru.touchin.roboswag.components.utils.UiUtils
|
||||
|
||||
abstract class KeyboardResizeableViewController<TActivity : BaseActivity, TState : Parcelable>(
|
||||
@LayoutRes layoutRes: Int,
|
||||
creationContext: CreationContext
|
||||
) : ViewController<TActivity, TState>(
|
||||
creationContext,
|
||||
layoutRes
|
||||
) {
|
||||
init {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
|
||||
creationContext.container?.requestApplyInsets()
|
||||
}
|
||||
}
|
||||
|
||||
private var keyboardIsVisible: Boolean = false
|
||||
|
||||
private val keyboardHideListener = OnBackPressedListener {
|
||||
if (keyboardIsVisible) {
|
||||
UiUtils.OfViews.hideSoftInput(activity)
|
||||
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 onResume() {
|
||||
super.onResume()
|
||||
if (isHideKeyboardOnBackEnabled) activity.addOnBackPressedListener(keyboardHideListener)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
if (isHideKeyboardOnBackEnabled) activity.removeOnBackPressedListener(keyboardHideListener)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
activity.keyboardBehaviorDetector?.apply {
|
||||
setKeyboardHideListener {
|
||||
if (keyboardIsVisible) {
|
||||
onKeyboardHide()
|
||||
}
|
||||
keyboardIsVisible = false
|
||||
}
|
||||
setKeyboardShowListener { diff ->
|
||||
if (!keyboardIsVisible) {
|
||||
onKeyboardShow(diff)
|
||||
}
|
||||
keyboardIsVisible = true
|
||||
}
|
||||
startDetection()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
activity.keyboardBehaviorDetector?.apply {
|
||||
removeKeyboardHideListener()
|
||||
removeKeyboardShowListener()
|
||||
stopDetection()
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue