완성된 코드입니다.
import android.content.Context
import android.view.inputmethod.InputMethodManager
val inputMethodManager = activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
private fun hideKeyboard(inputMethodManager: InputMethodManager, view: View) {
inputMethodManager.hideSoftInputFromWindow(view.windowToken, 0);
view.clearFocus()
}
안드로이드 스튜디오를 이용해서 Bottom Navigation Activity를 생성하여 시작하였습니다.
안드로이드에서 엔터키 등을 누를 때, soft keyboard를 숨기려고 했는데 안되는 겁니다!
당연히 Keyboard라는 Utility 클래스가 있어서 Keyboard.hide()하면 될줄 알았습니다.
구글링 해보니 InputMethodManager.hideSoftInputFromWindow()를 실행해야 하더군요!
InputMethodManager imm=(InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
방식이 제일 많이 사용되더군요.
하 지 만
코틀린에서는 activity.getSystemService()하는데 안되더군요...
InputMethodManager를 불러오기 위해선 activity가 있는지 모르기 때문에 activity?.getSystemService()을 사용할 수 있었습니다.
현재 foucs된 view를 가져오거나 윈도우 토큰을 이용해서 view를 주입하여 키보드를 닫아보았습니다.
import android.app.Activity
public static void hideKeyboard(Activity activity) {
var imm = (InputMethodManager) activity?.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
var view = activity?.currentFocus
if (view == null) {view = View(activity)}
imm.hideSoftInputFromWindow(view.windowToken, 0);
}
오... 상식이 박살나 버렸습니다..
EditText에서는 작동하지 않는겁니다! 크흐 멋지다 안드로이드!
Fragment가 떠있는 동안에는 Fragment의 Activity를 EditText가 사용할 수 없다고 하네요. 하하하하 :)
더 망가지는 나의 코드~
또 한번의 삽을 프니..
Fragment에서 Context를 불러올 수 없는 겁니다 ㅠㅠ
INPUT_METHOD_SERVICE를 갖고있는 Context를 찾을 수가 없더군요..
키보드 하나 내리는데... Context와 View / Window가 필요하다니 뭐 조금 생각해보니. 이해는 갔습니다.
keyboard가 독립적으로 나오는것이 아니라는것에 좀 의아했죠.
public static void hideKeyboardFrom(Context context, View view) {
InputMethodManager imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}
아.. 파라미터 2개 생기고 넘나 아름답네요...
WindowsoftInputMode의 설정값
안드로이는 첫번째 EditText에 초기 포커스 자동적으로 할당하거나 Activity에 focusable을 할당합니다.
일반적으로 Input매쏘드에 따라 fouct이벤트가 반응해야 합니다.
AndroidManifest.xml에서 windowSoftInputMode의 stateAlwaysHidden으로 속성을 설정하면, 초기 포커스 설정이 무시됩니다.
<activity
android:name=".MyActivity"
android:windowSoftInputMode="stateAlwaysHidden"/>
windowSoftInputMode세팅은 자동 focus 이벤트에만 적용되고, 터치 이벤트에 대해서는 적용 안 됩니다.
크 stateAlwaysHidden이라는 말보다는 ignoreInitalFocus가 훨신 어울리는 네이밍일텐데요.. 엄청 오해를 사게 만드네요.
윈도우 토큰을 얻는 다른 방법
view에 포커싱이 안된다면(Fragment를 바꾸었을 경우)
if (view == null) view = View(activity) 대신에
view = root.windowToken
로 대체합니다.
키보드가 보이는 포커싱을 지우고 싶을 때(백그라운드에서 어플을 열경우)
매소드 맨 마지막줄에 추가해주세요
view.clearFocus();
위 글에서 투표수가 제일 많은 답변을 재미있게 바꾸어 보았습니다.
저도 2시간정도 소모했던 ㅠㅠ 삽질이였네요! 저처럼 시간버리는분이 없으셨길 바랍니다!
'프로그래밍 > Android' 카테고리의 다른 글
안드로이드 스튜디오 Gson import [gradle] (0) | 2023.03.11 |
---|---|
안드로이드 에뮬레이터의 인터넷이 안될 때! (0) | 2021.02.08 |