프래그먼트 - Android 소프트 키보드 닫기/숨기기




안드로이드 프래그먼트 키보드 내리기 (20)

레이아웃에 EditTextButton 이 있습니다.

편집 필드에 쓰고 Button 클릭 한 후 가상 키보드를 숨기려고합니다. 이 코드는 간단한 코드라고 가정하지만 어디에서 예제를 찾을 수 있습니까?


짧은 대답

OnClick 수신기에서 onEditorAction 을 사용하여 EditTextonEditorAction 을 호출하십시오.

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        someEditText.onEditorAction(EditorInfo.IME_ACTION_DONE)
    }
});

드릴 다운

이 방법이 Android의 디자인 패턴에 더 좋고, 더 간단하고, 정렬되어 있다고 느낍니다. 위의 간단한 예에서 (일반적으로 대부분의 일반적인 경우) 포커스가있는 / 편집 된 EditText 가 있으며 대개 처음부터 키보드를 호출하는 EditText 가있을 것입니다 (확실히 키보드에서 호출 할 수 있습니다 많은 일반적인 시나리오). 똑같은 방식으로 키보드를 ImeAction 합니다. 일반적으로 ImeAction 으로 수행 할 수 있습니다. android:imeOptions="actionDone" 이있는 EditText 가 어떻게 작동하는지보고, 똑같은 방법으로 같은 행동을하고 싶습니다.

관련 답변 확인


IMM 키보드를 표시 할 수 없도록 사용자 정의 키보드를 사용하여 16 진수를 입력하고 있습니다 ...

v3.2.4_r1에서는 날씨를 제어하거나 TextView에 포커스가있을 때 키보드를 표시하지 않도록 setSoftInputShownOnFocus(boolean show) 가 추가되었지만 여전히 숨겨져 있으므로 리플렉션을 사용해야합니다.

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) {
    try {
        Method method = TextView.class.getMethod("setSoftInputShownOnFocus", boolean.class);
        method.invoke(mEditText, false);
    } catch (Exception e) {
        // Fallback to the second method
    }
}

이전 버전의 경우 OnGlobalLayoutListener 사용하여 매우 좋은 결과를 얻었지만 (완벽 OnGlobalLayoutListener , 루트보기의 ViewTreeObserver 를 사용하여 추가 한 다음 키보드가 다음과 같이 표시되는지 확인하십시오.

@Override
public void onGlobalLayout() {
    Configuration config = getResources().getConfiguration();

    // Dont allow the default keyboard to show up
    if (config.keyboardHidden != Configuration.KEYBOARDHIDDEN_YES) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(mRootView.getWindowToken(), 0);
    }
}

이 마지막 솔루션은 키보드를 초 단위로 표시하고 선택 핸들로 엉망이 될 수 있습니다.

키보드에서 전체 화면으로 전환하면 onGlobalLayout이 호출되지 않습니다. 이를 방지하려면 TextView#setImeOptions(int) 또는 TextView XML 선언을 사용하십시오.

android:imeOptions="actionNone|actionUnspecified|flagNoFullscreen|flagNoExtractUi"

업데이트 : 키보드를 표시하지 않고 모든 버전에서 작동하는 대화 상자를 발견했습니다.

getWindow().setFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM,
        WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);

그래서 검색에서 여기에 나를 위해 일하는 대답을 발견

// Show soft-keyboard:
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);

// Hide soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

또한 소프트 키보드를 숨기는 데 유용합니다.

getWindow().setSoftInputMode(
    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN
);

이것은 사용자가 실제로 editText View를 터치 할 때까지 소프트 키보드를 억제하는 데 사용될 수 있습니다.


여기에있는 다른 모든 대답이 원하는대로 작동하지 않으면 수동으로 키보드를 제어 할 수있는 또 다른 방법이 있습니다.

EditText 의 속성 중 일부를 관리 할 함수를 만듭니다.

public void setEditTextFocus(boolean isFocused) {
    searchEditText.setCursorVisible(isFocused);
    searchEditText.setFocusable(isFocused);
    searchEditText.setFocusableInTouchMode(isFocused);

    if (isFocused) {
        searchEditText.requestFocus();
    }
}

그런 다음 편집 텍스트의 onFocus를 열거 나 키보드를 닫습니다.

searchEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (v == searchEditText) {
            if (hasFocus) {
                // Open keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).showSoftInput(searchEditText, InputMethodManager.SHOW_FORCED);
            } else {
                // Close keyboard
                ((InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(searchEditText.getWindowToken(), 0);
            }
        }
    }
});

이제 키보드를 수동으로 열려고 할 때마다 다음을 호출하십시오.

setEditTextFocus(true);

전화 끊기 :

setEditTextFocus(false);

이 광기를 명확히하기 위해, 나는 안드로이드 사용자를 대신하여 소프트 키보드에 대한 Google의 완전히 우스운 취급에 대해 사과하는 것으로 시작하고 싶습니다. 똑같은 질문에 대해 여러 가지 답변이 많이 존재하는 이유는 Android의 다른 많은 사람들처럼이 API가 끔찍하게 설계 되었기 때문입니다. 나는 그것을 정중하게 말할 방법이 없다고 생각할 수있다.

키보드를 숨기고 싶습니다. 안드로이드에게 Keyboard.hide() 문을 제공 할 것을 기대합니다. 끝. 고맙습니다. 하지만 안드로이드는 문제가있다. 키보드를 숨기려면 InputMethodManager 를 사용해야합니다. 좋아요. 안드로이드의 키보드 API입니다. 그러나! IMM에 액세스하려면 Context 가 있어야합니다. 이제 우리에게는 문제가 있습니다. 어떤 Context 를 사용하거나 필요로하지 않는 정적 또는 유틸리티 클래스에서 키보드를 숨길 수 있습니다. 또는 더 나쁜 것은, IMM은 키보드를 FROM으로 숨기려는 View (또는 더 나쁜 경우, 어떤 Window )를 지정해야한다고 요구합니다.

이것이 키보드를 숨기는 것을 어렵게 만드는 이유입니다. 친애하는 구글 : 내가 케이크를위한 요리법을 찾고있을 때, 내가 먼저 케이크에 먹을 것 인 곳에 대답하지 않는 한, 요리법을 나에게 제공하기를 거부 할 지구상의 어떤 RecipeProvider 도 없다.

이 슬픈 이야기는 추악한 사실로 끝납니다. Android 키보드를 숨기려면 ContextView 또는 Window 두 가지 형태의 ID를 제공해야 Window .

Activity 에서 호출하면 매우 안정적으로 작업을 수행 할 수있는 정적 유틸리티 메서드를 만들었습니다.

public static void hideKeyboard(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    //Find the currently focused view, so we can grab the correct window token from it.
    View view = activity.getCurrentFocus();
    //If no view currently has focus, create a new one, just so we can grab a window token from it
    if (view == null) {
        view = new View(activity);
    }
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

이 유틸리티 메소드는 Activity 에서 호출 할 때만 작동합니다! 위의 메서드는 대상 Activity getCurrentFocus 를 호출하여 적절한 창 토큰을 가져옵니다.

DialogFragment 호스트 된 EditText 에서 키보드를 숨기고 싶다고합시다. 위의 방법을 사용할 수 없습니다.

hideKeyboard(getActivity()); //won't work

이것은 Fragment 의 호스트 Activity 대한 참조를 전달할 것이기 때문에 작동하지 않을 것입니다. Fragment 가 표시되어있는 동안 집중된 컨트롤이 없습니다! 와우! 그래서 키보드를 조각들로부터 숨기기 위해서, 나는 더 낮은 레벨의, 더 보편적이고 더 못된 것에 의존한다 :

public static void hideKeyboardFrom(Context context, View view) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
}

다음은이 솔루션을 쫓는 데 더 많은 시간을 낭비하는 몇 가지 추가 정보입니다.

windowSoftInputMode 정보

알고 있어야 할 또 다른 논점이 있습니다. 기본적으로 Android는 처음 포커스를 Activity 의 첫 번째 EditText 또는 포커스 가능 컨트롤에 자동으로 할당합니다. 자연스럽게 InputMethod (일반적으로 소프트 키보드)는 포커스 이벤트에 응답하여 응답합니다. AndroidManifest.xmlwindowSoftInputMode 속성이 windowSoftInputMode 설정되면 키보드에 자동으로 할당 된이 초기 포커스를 무시하도록 지시합니다.

<activity
    android:name=".MyActivity"
    android:windowSoftInputMode="stateAlwaysHidden"/>

거의 믿을 수 없을 정도로, ( focusable="false" 및 / 또는 focusableInTouchMode="false" 가 컨트롤에 할당되지 않는 한) 컨트롤을 터치 할 때 키보드가 열리지 않도록하는 것은 아무 것도없는 것처럼 보입니다. 분명히 windowSoftInputMode 설정은 터치 이벤트에서 트리거 된 이벤트를 집중시키는 것이 아니라 자동 포커스 이벤트에만 적용됩니다.

따라서 stateAlwaysHidden 은 실제로 매우 잘못 명명되었습니다. 대신 ignoreInitialFocus 라고해야합니다.

희망이 도움이됩니다.

UPDATE : 창 토큰을 얻는 더 많은 방법

집중된 뷰가 없으면 (예를 들어 방금 조각을 변경 한 경우), 유용한 창 토큰을 제공 할 다른 뷰가 있습니다.

위 코드의 대안은 다음과 같습니다 if (view == null) view = new View(activity); 이것들은 당신의 활동을 명시 적으로 지칭하지 않습니다.

조각 클래스 내부 :

view = getView().getRootView().getWindowToken();

매개 변수로 조각 fragment 주어 졌을 때 :

view = fragment.getView().getRootView().getWindowToken();

콘텐츠 본문에서 시작 :

view = findViewById(android.R.id.content).getRootView().getWindowToken();

업데이트 2 : 배경에서 앱을 열면 다시 키보드가 보이지 않도록 포커스를 지우십시오.

이 줄을 메서드의 끝에 추가합니다.

view.clearFocus();


이것을 사용하십시오.

this.getWindow().setSoftInputMode(
            WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

키보드를 숨길 수있는 솔루션이 하나 더 있습니다.

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);

여기에서는 showFlag 의 위치에서 HIDE_IMPLICIT_ONLY 를 전달하고 HIDE_IMPLICIT_ONLY 의 위치에서 0hiddenFlag 합니다. 그것은 부드러운 키보드를 강제로 닫을 것입니다.


onCreate() 에서 아래 코드를 시도하십시오.

EditText edtView=(EditText)findViewById(R.id.editTextConvertValue);
edtView.setInputType(0);

업데이트 : 이 솔루션이 더 이상 작동하지 않는 이유를 모르겠습니다 (Android 23에서 방금 테스트했습니다). 대신 Saurabh Pareek 솔루션을 사용하십시오. 여기있어:

InputMethodManager imm = (InputMethodManager) getSystemService(Activity.INPUT_METHOD_SERVICE);
//Hide:
imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
//Show
imm.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);

이전 답변 :

//Show soft-keyboard:
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//hide keyboard :
 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

나는 거의 모든 답변을 시도했지만, 나는 삼성 전자 은하 s5와 특히 임의의 문제가있었습니다.

내가 끝내는 것은 쇼와 숨을 강제하는 것입니다. 그리고 그것은 완벽하게 작동합니다 :

/**
 * Force show softKeyboard.
 */
public static void forceShow(@NonNull Context context) {
    InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
}

/**
 * Force hide softKeyboard.
 */
public static void forceHide(@NonNull Activity activity, @NonNull EditText editText) {
    if (activity.getCurrentFocus() == null || !(activity.getCurrentFocus() instanceof EditText)) {
        editText.requestFocus();
    }
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
    activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}

다음은 Android 용 Mono (AKA MonoDroid)에서 수행하는 방법입니다.

InputMethodManager imm = GetSystemService (Context.InputMethodService) as InputMethodManager;
if (imm != null)
    imm.HideSoftInputFromWindow (searchbox.WindowToken , 0);

장치 또는 기능 테스트 중에 소프트 키보드를 닫으려면 테스트에서 "뒤로 단추"를 클릭하십시오.

// Close the soft keyboard from a Test
getInstrumentation().sendKeyDownUpSync(KeyEvent.KEYCODE_BACK);

위의 내용 onBackPressed()은 해당 활동에 대한 트리거가 아니므로 "뒤로 버튼"을 따옴표로 묶습니다 . 그냥 키보드를 닫을뿐입니다.

계속 진행하기 전에 잠시 멈추십시오. 뒤로 버튼을 닫는 데 약간의 시간이 걸리므로 짧은 일시 중지 (1 초가 충분할 때까지) 등의 후속 클릭은 등록되지 않습니다 ).


활동에 최적화 된 코드를 사용하십시오.

if (this.getCurrentFocus() != null) {
    InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
    inputManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}

간단하고 사용하기 쉬운 메소드입니다. hideKeyboardFrom (YourActivity.this)을 호출 하십시오. 키보드를 숨기는 방법

/**
 * This method is used to hide keyboard
 * @param activity
 */
public static void hideKeyboardFrom(Activity activity) {
    InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
}

경우에 따라이 메소드는 다른 모든 메소드를 제외하고는 작동 할 수 있습니다. 이것은 내 하루를 절약 할 수 :)

public static void hideSoftKeyboard(Activity activity) {
    if (activity != null) {
        InputMethodManager inputManager = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (activity.getCurrentFocus() != null && inputManager != null) {
            inputManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0);
            inputManager.hideSoftInputFromInputMethod(activity.getCurrentFocus().getWindowToken(), 0);
        }
    }
}

public static void hideSoftKeyboard(View view) {
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        if (inputManager != null) {
            inputManager.hideSoftInputFromWindow(view.getWindowToken(), 0);
        }
    }
}

위의 답변은 다양한 시나리오에서 작동하지만 보기에서 키보드를 숨기고 올바른 컨텍스트를 얻으려고 애쓰는 경우 다음을 시도하십시오.

setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        hideSoftKeyBoardOnTabClicked(v);
    }
}

private void hideSoftKeyBoardOnTabClicked(View v) {
    if (v != null && context != null) {
        InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

컨텍스트를 가져 와서 생성자에서 가져옵니다. :)

public View/RelativeLayout/so and so (Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    this.context = context;
    init();
}

이 SO 응답 덕분에 , 필자는 ViewPager의 조각을 스크롤 할 때 내 작품에서 멋지게 작동하는 다음을 도출했습니다 ...

private void hideKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    }
}

private void showKeyboard() {   
    // Check if no view has focus:
    View view = this.getCurrentFocus();
    if (view != null) {
        InputMethodManager inputManager = (InputMethodManager) this.getSystemService(Context.INPUT_METHOD_SERVICE);
        inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT);
    }
}

제 경우에는 액션 바에서 SearchView를 사용하고있었습니다. 사용자가 검색을 수행하면 키보드가 다시 열립니다.

InputMethodManager를 사용해도 키보드가 닫히지 않았습니다. 초점을 맞추고 검색보기의 초점을 false로 설정해야했습니다.

mSearchView.clearFocus();
mSearchView.setFocusable(false);

protected void hideSoftKeyboard(EditText input) {
    input.setInputType(0);
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(input.getWindowToken(), 0);    
}




soft-keyboard