package com.xxx.xxx.utils
import android.view.View
import android.view.Window
import androidx.core.view.ViewCompat
import androidx.core.view.WindowCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.Fragment
object KeyboardUtils {
private val KEYBOARD = WindowInsetsCompat.Type.ime()
private val NAVIGATION_BAR = WindowInsetsCompat.Type.navigationBars()
fun registerKeyboardListener(
window: Window?,
block: (currentFocusView: View?, imeVisible: Boolean) -> Unit
) {
window?.decorView?.rootView?.let { windowView ->
Log.d("KeyboardListener","KeyboardListener==>register")
val listener = androidx.core.view.OnApplyWindowInsetsListener { view, insets ->
window.currentFocus?.let {
val imeVisible = insets.isVisible(KEYBOARD)
Logr.d("KeyboardListener","KeyboardListener==>keyboardShown:$imeVisible")
block.invoke(window.currentFocus, imeVisible)
}
ViewCompat.onApplyWindowInsets(view, insets)
}
ViewCompat.setOnApplyWindowInsetsListener(windowView, listener)
}
}
fun registerKeyboardListenerWithOffset(
window: Window?,
block: (currentFocusView: View?, offset: Int) -> Unit
) {
window?.decorView?.rootView?.let { windowView ->
Log.d("KeyboardListener","KeyboardListener==>register")
val windowHeight = windowView.height
var keyboardHeight = -1
val focusLocation = IntArray(2)
var lastOffset = -1
val listener = androidx.core.view.OnApplyWindowInsetsListener { view, insets ->
window.currentFocus?.let let2@{ focusView ->
if (keyboardHeight <= 0) {
keyboardHeight = insets.getInsets(KEYBOARD).bottom
}
val keyboardTop = windowHeight - keyboardHeight
focusView.getLocationInWindow(focusLocation)
val editBottom = (focusLocation[1] + focusView.bottom)
val newOffset = editBottom - keyboardTop
Log.d("KeyboardListener","KeyboardListener==>offset:$keyboardHeight|$editBottom|$newOffset")
//keyboard shown
if (lastOffset < 0 && newOffset > 0) {
block.invoke(focusView, newOffset)
lastOffset = newOffset
return@let2
}
//keyboard hidden
if (lastOffset > 0) {
block.invoke(focusView, -lastOffset)
lastOffset = -1
return@let2
}
}
ViewCompat.onApplyWindowInsets(view, insets)
}
ViewCompat.setOnApplyWindowInsetsListener(windowView, listener)
}
}
fun unregisterKeyboardListener(window: Window?) {
window?.decorView?.rootView?.let { rootView ->
ViewCompat.setOnApplyWindowInsetsListener(rootView, null)
Log.d("KeyboardListener==>unregister")
}
}
/**
* @return null | means Exception occurred.
*/
fun isKeyboardVisible(fragment: Fragment?, isEmbeddedFragment: Boolean = false): Boolean? {
val windowFragment = if (isEmbeddedFragment) {
fragment?.parentFragment
} else {
fragment
}
val window: Window? = if (windowFragment is DialogFragment) {
windowFragment.dialog?.window
} else {
windowFragment?.activity?.window
}
window?.let { myWindow ->
val rootView = myWindow.decorView.rootView ?: return null
val windowInsetsCompat = ViewCompat.getRootWindowInsets(rootView) ?: return null
return windowInsetsCompat.isVisible(KEYBOARD)
}
return null
}
fun getSystemWindow(fragment: Fragment?, isEmbeddedFragment: Boolean = false): Window? {
val windowFragment = if (isEmbeddedFragment) {
fragment?.parentFragment
} else {
fragment
}
val window: Window? = if (windowFragment is DialogFragment) {
windowFragment.dialog?.window
} else {
windowFragment?.activity?.window
}
return window
}
fun getNavigationBarHeight() {
// val isNavigationBarVisibleVar =ViewCompat.getRootWindowInsets(rootView)?.isVisible(NAVIGATION_BAR) == true
// val navigationBarHeight = if (isKeyboardVisibleVar && isNavigationBarVisibleVar) {
// windowInsetsCompatVar?.getInsets(NAVIGATION_BAR)?.bottom ?: 0
// } else {
// 0
// }
// rootView.updatePadding(bottom = -navigationBarHeight)
}
fun setKeyboardListenerByGlobalLayout(){
// val parentView = mBinding.root
// parentView.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
// private var alreadyOpen = false
// private val defaultKeyboardHeightDP = 100
// private val EstimatedKeyboardDP =
// defaultKeyboardHeightDP + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) 48 else 0
// private val rect: Rect = Rect()
// override fun onGlobalLayout() {
// val estimatedKeyboardHeight = TypedValue.applyDimension(
// TypedValue.COMPLEX_UNIT_DIP,
// EstimatedKeyboardDP.toFloat(),
// parentView.resources.displayMetrics
// ).toInt()
// parentView.getWindowVisibleDisplayFrame(rect)
// val heightDiff: Int = parentView.rootView.height - (rect.bottom - rect.top)
// val isShown = heightDiff >= estimatedKeyboardHeight
// if (isShown == alreadyOpen) {
// ConversationLog.i("Keyboard state", "Ignoring global layout change...")
// return
// }
// alreadyOpen = isShown
// onKeyboardVisibilityListener.onKeyboardVisibilityChanged(isShown)
// }
// })
}
}
-----------------------------End-----------------------------
网友评论