Skip to content

Instantly share code, notes, and snippets.

@thegarlynch
Last active August 3, 2021 08:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thegarlynch/d92b5ecca5be2bbd12dca05e8a74ce87 to your computer and use it in GitHub Desktop.
Save thegarlynch/d92b5ecca5be2bbd12dca05e8a74ce87 to your computer and use it in GitHub Desktop.
import android.content.Context
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
private fun View.getMethodManager() : InputMethodManager {
return context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
}
fun View.showKeyboard(){
getMethodManager().toggleSoftInputFromWindow(windowToken, InputMethodManager.SHOW_FORCED, 0)
}
fun View.hideKeyboard(){
getMethodManager().hideSoftInputFromWindow(windowToken, 0)
}
// Only uses this when you change softInput in manifest
fun EditText.attachKeyboard(container: View) {
setOnFocusChangeListener { _ , hasFocus ->
if(hasFocus){
container.showKeyboard()
}else{
container.hideKeyboard()
}
}
}
import android.content.Context
import android.view.View
import android.view.ViewTreeObserver
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import androidx.annotation.IdRes
import com.thegar.viewhelper.R
/***
* Show keyboard on [EditText]
*
* Better Implementation of showing keyboard
* - Keyboard will be automatically dismissed when navigating to other application
* - it did not need hideKeyboard method
*
* [link](https://developer.squareup.com/blog/showing-the-android-keyboard-reliably/)
*/
fun EditText.showKeyboard() {
fun EditText.showTheKeyboardNow() {
if (isFocused) {
post {
// We still post the call, just in case we are being notified of the windows focus
// but InputMethodManager didn't get properly setup yet.
val keyboardBelow = getTag(R.id.ShowKeyboardBelow) as? View ?: this
getMethodManager().showSoftInput(keyboardBelow, InputMethodManager.SHOW_IMPLICIT)
}
}
}
if (hasWindowFocus()) {
showTheKeyboardNow()
} else {
// Wait until the window gets focus.
runOnWindowFocus { showTheKeyboardNow() }
}
}
/**
* This is placed inside of any Focusable Widget
*/
internal fun View.hideKeyboard(){
getMethodManager().hideSoftInputFromWindow(windowToken, 0)
}
internal fun View.runOnWindowFocus(block : () -> Unit){
viewTreeObserver.addOnWindowFocusChangeListener(
object : ViewTreeObserver.OnWindowFocusChangeListener {
override fun onWindowFocusChanged(hasFocus: Boolean) {
// This notification will arrive just before the InputMethodManager gets set up.
if (hasFocus) {
block.invoke()
// It’s very important to remove this listener once we are done.
viewTreeObserver.removeOnWindowFocusChangeListener(this)
}
}
}
)
}
internal fun View.getMethodManager() : InputMethodManager {
return context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
}
/***
* Attach A View to EditText,
* You should reattach keyboard whenever [EditText] is detached from window
*
* @param keyboardBelowView : Keyboard will be shown below this view
*/
fun EditText.attachKeyboard(keyboardBelowView: View) {
setTag(R.id.ShowKeyboardBelow, keyboardBelowView)
setOnFocusChangeListener { _ , hasFocus ->
if(hasFocus){
showKeyboard()
}
}
// fix possible memory leak
addOnAttachStateChangeListener(PreventLeakingTag(R.id.ShowKeyboardBelow))
}
fun EditText.attachKeyboard(){
setOnFocusChangeListener { _ , hasFocus ->
if(hasFocus){
showKeyboard()
}
}
}
internal class PreventLeakingTag(
@IdRes private val tagId : Int
) : View.OnAttachStateChangeListener {
override fun onViewAttachedToWindow(v: View?) { }
override fun onViewDetachedFromWindow(v: View?) {
v?.setTag(tagId, null)
v?.removeOnAttachStateChangeListener(this)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment