Created
October 30, 2018 13:37
-
-
Save Tagakov/9bfc1cd6b31ef22cf489055715ae2944 to your computer and use it in GitHub Desktop.
Allows to hide and show keyboard with notification after successful hiding or showing
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
@Reusable | |
class RxKeyboardManager(private val activity: Activity, private val mainThread: Scheduler, private val imm: InputMethodManager) { | |
val keyboardStates = Observable.create<Boolean>({ | |
val globalLayoutListener = ViewTreeObserver.OnGlobalLayoutListener { it.onNext(isKeyboardShown()) } | |
it.setCancellation { activity.window.decorView.viewTreeObserver.removeOnGlobalLayoutListener(globalLayoutListener) } | |
activity.window.decorView.viewTreeObserver.addOnGlobalLayoutListener(globalLayoutListener) | |
}, Emitter.BackpressureMode.LATEST) | |
.distinctUntilChanged() | |
.subscribeOn(mainThread) | |
.share() | |
fun isKeyboardShown(): Boolean { | |
val rootView = activity.window.decorView | |
/* 128dp = 32dp * 4, minimum button height 32dp and generic 4 rows soft keyboard */ | |
val SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD = 128 | |
val r = Rect() | |
rootView.getWindowVisibleDisplayFrame(r) | |
val dm = rootView.resources.displayMetrics | |
/* heightDiff = rootView height - status bar height (r.top) - visible frame height (r.bottom - r.top) */ | |
val heightDiff = rootView.bottom - r.bottom | |
/* Threshold size: dp to pixels, multiply with display density */ | |
return heightDiff > SOFT_KEYBOARD_HEIGHT_DP_THRESHOLD * dm.density | |
} | |
@CheckResult | |
fun showKeyboard(viewForInput: View): Completable = if (isKeyboardShown()) { | |
Completable.complete() | |
} else { | |
Completable.fromAction { imm.showSoftInput(viewForInput, 0) } | |
.concatWith(keyboardReacted(visibility = true)) | |
} | |
@CheckResult | |
@JvmOverloads | |
fun hideKeyboard(view: View = activity.window.decorView): Completable = if (isKeyboardShown()) { | |
Completable.fromAction { imm.hideSoftInputFromWindow(view.windowToken, 0) } | |
.concatWith(keyboardReacted(visibility = false)) | |
} else { | |
Completable.complete() | |
} | |
private fun keyboardReacted(visibility: Boolean): Completable = keyboardStates | |
.first { it == visibility } | |
.observeOn(mainThread)// Wait when UI reflected (a small delay because of post()) | |
.toCompletable() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment