Added inset keyboard detect

This commit is contained in:
Aksenov Vladimir 2019-09-09 16:29:38 +03:00
parent ad4712d770
commit 297937b643
1 changed files with 40 additions and 52 deletions

View File

@ -1,67 +1,55 @@
package ru.touchin.roboswag.components.navigation.keyboard_resizeable
import android.graphics.Rect
import android.view.View
import android.view.ViewGroup
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import ru.touchin.roboswag.components.navigation.activities.BaseActivity
// The workaround forces an activity to resize when keyboard appears in the full-screen mode
/**
* This detector NOT detect landscape fullscreen keyboard
*
* You activity must have android:windowSoftInputMode="adjustResize" at least, otherwise listeners won't be called
*/
class KeyboardBehaviorDetector(
activity: BaseActivity,
fragmentContainerId: Int
activity: BaseActivity
) {
companion object {
private const val SCREEN_TO_KEYBOARD_HEIGHT_RATIO = 4.75
}
private val view = activity.window.decorView
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() }
var keyboardHideListener: (() -> Unit)? = null
var keyboardShowListener: ((Int) -> Unit)? = null
private var keyboardHideListener: (() -> Unit)? = null
private var keyboardShowListener: ((Int) -> Unit)? = null
var startNavigationBarHeight = -1
private set
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 / SCREEN_TO_KEYBOARD_HEIGHT_RATIO) {
keyboardShowListener?.invoke(diff)
private val listener = { isKeyboardOpen: Boolean,
windowInsets: WindowInsetsCompat ->
if (isKeyboardOpen) {
keyboardShowListener?.invoke(
windowInsets.systemWindowInsetBottom - startNavigationBarHeight
)
} else {
keyboardHideListener?.invoke()
}
}
// Call this in "onResume()" of a fragment
fun startDetection() {
ViewCompat.setOnApplyWindowInsetsListener(view) { _, windowInsets ->
val bottomInset = windowInsets.systemWindowInsetBottom
listener(isKeyboardOpen(bottomInset), windowInsets)
if (startNavigationBarHeight == -1) startNavigationBarHeight = bottomInset
windowInsets
}
}
// Call this in "onPause()" of a fragment
fun stopDetection() {
ViewCompat.setOnApplyWindowInsetsListener(view, null)
}
private fun isKeyboardOpen(navigationHeight: Int) =
navigationHeight != startNavigationBarHeight && startNavigationBarHeight != -1
}