Created
November 30, 2020 06:23
-
-
Save zkywalker/489c333fb297d772632614ca159dce45 to your computer and use it in GitHub Desktop.
监听键盘弹起,在键盘上面悬浮视图
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.app.Activity | |
import android.content.Context | |
import android.graphics.Rect | |
import android.support.constraint.ConstraintLayout | |
import android.util.AttributeSet | |
import android.view.Gravity | |
import android.view.View | |
import android.view.ViewGroup | |
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT | |
import android.widget.FrameLayout | |
/** | |
* 输入法上悬浮框(没有使用单独的window实现,直接加在原有的decor view内) | |
*/ | |
open class InputFloatView @JvmOverloads constructor(context: Context, attributeSet: AttributeSet? = null, defThemeInt: Int = 0) | |
: ConstraintLayout(context, attributeSet, defThemeInt) { | |
var activity: Activity? = null | |
var isListening = true | |
open var customInputViewThreshold: Int? = null | |
open var needFixStatusBar: Boolean = false | |
private var listener: ((view: View, isShow: Boolean, inputViewHeight: Int) -> Unit)? = null | |
init { | |
if (context is Activity) { | |
register(context) | |
} | |
} | |
fun register(activity: Activity, needFixStatusBar: Boolean = false) { | |
this.activity = activity | |
val decorView = activity.window.decorView | |
this.needFixStatusBar = needFixStatusBar | |
decorView.viewTreeObserver.addOnGlobalLayoutListener { | |
if (!isListening) { | |
return@addOnGlobalLayoutListener | |
} | |
val r = Rect() | |
// 注意我们是沉浸式的页面,这个地方会少算一个status bar的高度 | |
decorView.getWindowVisibleDisplayFrame(r) | |
val screenHeight = decorView.height | |
val heightDifference = screenHeight - (r.bottom - r.top) | |
// todo 能不能主动获取是否是沉浸式的页面? | |
val fixStatusBar = if (this.needFixStatusBar) { | |
getStatusHeight() | |
} else { | |
0 | |
} | |
if (this.parent == null) { | |
val layoutParams = initLayoutParams() | |
layoutParams.gravity = Gravity.BOTTOM | |
(decorView as? ViewGroup)?.addView(this, layoutParams) | |
} | |
if (heightDifference > customInputViewThreshold ?: INPUT_VIEW_THRESHOLD) { | |
val inputViewHeight = heightDifference - fixStatusBar | |
(this.layoutParams as? ViewGroup.MarginLayoutParams)?.bottomMargin = inputViewHeight | |
this.visibility = View.VISIBLE | |
this.listener?.invoke(this, true, heightDifference) | |
} else { | |
this.visibility = View.GONE | |
this.listener?.invoke(this, false, heightDifference) | |
} | |
} | |
} | |
fun setOnInputViewToggleListener(listener: ((view: View, isShow: Boolean, inputViewHeight: Int) -> Unit)?) { | |
this.listener = listener | |
} | |
open fun initLayoutParams(): FrameLayout.LayoutParams = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT) | |
companion object { | |
/** | |
* 随便写了个输入法高度阈值 | |
*/ | |
const val INPUT_VIEW_THRESHOLD = 800 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment