Skip to content

Instantly share code, notes, and snippets.

@kimji1
Last active August 24, 2022 10:15
Show Gist options
  • Save kimji1/98eaf30adae41b58df218ee6bd1140d3 to your computer and use it in GitHub Desktop.
Save kimji1/98eaf30adae41b58df218ee6bd1140d3 to your computer and use it in GitHub Desktop.
/**
* example (use in fragment) >
* viewLifecycleOwner.lifecycle.addObserver(
* FocusClearLifecycleObserver(binding.root, requireActivity()) {
* binding.editText.clearFocus()
* })
*
* example (use in activity) >
* lifecycle.addObserver(
* FocusClearLifecycleObserver(binding.root, this) {
* binding.editText.clearFocus()
* })
*/
class FocusClearLifecycleObserver(
rootView: View,
activity: Activity,
val clearViewFocus: (() -> Unit)
) : LifecycleObserver {
private var rootView: View? = null
private var activity: Activity? = null
init {
this.rootView = rootView
this.activity = activity
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
fun init() {
if (rootView == null) {
return
}
setLayoutChangeListener()
setClearFocusClickListener(rootView as ViewGroup)
}
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
fun release() {
rootView = null
activity = null
}
private fun clearFocus() {
activity?.hideKeyboard(clearViewFocus)
}
private fun setLayoutChangeListener() {
rootView?.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
if (activity?.isKeyboardVisible() == false) {
clearFocus()
}
}
}
@SuppressLint("ClickableViewAccessibility")
private fun setClearFocusClickListener(viewGroup: ViewGroup) {
if (viewGroup is ScrollView || viewGroup is ScrollingView) {
viewGroup.viewTreeObserver.addOnScrollChangedListener {
clearFocus()
}
}
viewGroup.children.forEach { view ->
if (view is ViewGroup) {
setClearFocusClickListener(view)
}
if (view !is EditText && !view.hasOnClickListeners()) {
view.setOnClickListener {
clearFocus()
}
}
}
}
}
fun Activity.isKeyboardVisible(): Boolean {
val r = Rect()
val contentView: View = findViewById(android.R.id.content)
contentView.getWindowVisibleDisplayFrame(r)
val screenHeight: Int = contentView.rootView.height
val keypadHeight: Int = screenHeight - r.bottom
return keypadHeight > screenHeight * 0.15
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment