我的布局中有一个EditText和一个Button。

在编辑字段中写入并单击按钮后,我想在触摸键盘外部时隐藏虚拟键盘。我假设这是一段简单的代码,但我在哪里可以找到它的示例?


当前回答

当您想手动隐藏键盘时,单击按钮:

/**
 * Hides the already popped up keyboard from the screen.
 *
 */
public void hideKeyboard() {
    try {
        // use application level context to avoid unnecessary leaks.
        InputMethodManager inputManager = (InputMethodManager) getApplicationContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        assert inputManager != null;
        inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

当您想在屏幕上除编辑文本以外的任何地方隐藏键盘时在活动中重写此方法:

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
    View view = getCurrentFocus();
    if (view != null && (ev.getAction() == MotionEvent.ACTION_UP || ev.getAction() == MotionEvent.ACTION_MOVE) && view instanceof EditText && !view.getClass().getName().startsWith("android.webkit.")) {
        int scrcoords[] = new int[2];
        view.getLocationOnScreen(scrcoords);
        float x = ev.getRawX() + view.getLeft() - scrcoords[0];
        float y = ev.getRawY() + view.getTop() - scrcoords[1];
        if (x < view.getLeft() || x > view.getRight() || y < view.getTop() || y > view.getBottom())
            ((InputMethodManager)this.getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow((this.getWindow().getDecorView().getApplicationWindowToken()), 0);
    }
    return super.dispatchTouchEvent(ev);
}

其他回答

在如此的搜索中,我找到了一个适合我的答案

// 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);

如果有人感兴趣的话,我已经为Kotlin写了一个小扩展,但没有太多测试:

fun Fragment.hideKeyboard(context: Context = App.instance) {
    val windowToken = view?.rootView?.windowToken
    windowToken?.let {
        val imm = context.getSystemService(Activity.INPUT_METHOD_SERVICE) as InputMethodManager
        imm.hideSoftInputFromWindow(windowToken, 0)
    }
}

App.instance是存储在Application中的静态“this”Application对象

更新:在某些情况下,windowToken为空。我增加了使用反射来检测键盘是否关闭的额外关闭方式

/**
 * If no window token is found, keyboard is checked using reflection to know if keyboard visibility toggle is needed
 *
 * @param useReflection - whether to use reflection in case of no window token or not
 */
fun Fragment.hideKeyboard(context: Context = MainApp.instance, useReflection: Boolean = true) {
    val windowToken = view?.rootView?.windowToken
    val imm = context.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
    windowToken?.let {
        imm.hideSoftInputFromWindow(windowToken, 0)
    } ?: run {
        if (useReflection) {
            try {
                if (getKeyboardHeight(imm) > 0) {
                    imm.toggleSoftInput(0, InputMethodManager.HIDE_NOT_ALWAYS)
                }
            } catch (exception: Exception) {
                Timber.e(exception)
            }
        }
    }
}

fun getKeyboardHeight(imm: InputMethodManager): Int = InputMethodManager::class.java.getMethod("getInputMethodWindowVisibleHeight").invoke(imm) as Int

我创建了一个布局,部分来自xml,部分来自自定义布局引擎,所有这些都在代码中处理。对我来说,唯一有效的方法是跟踪键盘是否打开,并使用如下键盘切换方法:

public class MyActivity extends Activity
{
    /** This maintains true if the keyboard is open. Otherwise, it is false. */
    private boolean isKeyboardOpen = false;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        LayoutInflater inflater;
        inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View contentView = inflater.inflate(context.getResources().getIdentifier("main", "layout", getPackageName()), null);

        setContentView(contentView);
        contentView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() 
        {
            public void onGlobalLayout() 
            {
                Rect r = new Rect();
                contentView.getWindowVisibleDisplayFrame(r);
                int heightDiff = contentView.getRootView().getHeight() - (r.bottom - r.top);
                if (heightDiff > 100) 
                    isKeyboardVisible = true;
                else
                    isKeyboardVisible = false;
             });
         }
    }

    public void closeKeyboardIfOpen()
    {
        InputMethodManager imm;
        imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        if (isKeyboardVisible)
            imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0);
    }   
}

试试这个

简单,您可以在活动中调用


 public static void hideKeyboardwithoutPopulate(Activity activity) {
    InputMethodManager inputMethodManager =
            (InputMethodManager) activity.getSystemService(
                    Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(
            activity.getCurrentFocus().getWindowToken(), 0);
}

在您的主活动中调用


 hideKeyboardwithoutPopulate(MainActivity.this);

public static void closeInput(final View caller) {  
    caller.postDelayed(new Runnable() {
        @Override
        public void run() {
            InputMethodManager imm = (InputMethodManager) caller.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(caller.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }, 100);
}

此方法通常有效,但有一个条件:不能设置android:windowSoftInputMode=“any_of_themes”