Last active
August 3, 2021 08:31
-
-
Save thegarlynch/d92b5ecca5be2bbd12dca05e8a74ce87 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.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() | |
} | |
} | |
} |
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.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