android android隐藏软键盘 edittext失去焦点隐藏软键盘 - 关闭/隐藏Android软键盘




15 Answers

为了帮助澄清这种疯狂,我想首先代表所有Android用户道歉,谷歌对软键盘的彻头彻尾的荒谬处理。 对于同样简单的问题,有很多答案,每个不同的原因是因为这个API与Android中的许多其他答案一样,设计非常糟糕。 我可以想到没有礼貌的方式陈述它。

我想隐藏键盘。 我期望为Android提供以下声明: Keyboard.hide() 。 结束。 非常感谢你。 但Android存在问题。 您必须使用InputMethodManager来隐藏键盘。 好的,很好,这是Android的键盘API。 但! 您需要具有Context才能访问IMM。 现在我们遇到了问题。 我可能想要从没有任何使用或不需要任何Context的静态或实用程序类中隐藏键盘。 或者更糟糕的是,IMM要求您指定要隐藏键盘FROM的View (甚至更糟糕的是什么Window )。

这使得隐藏键盘变得如此具有挑战性。 亲爱的谷歌:当我查找蛋糕的配方时,地球上没有RecipeProvider拒绝向我提供配方,除非我第一次回答世界卫生组织,蛋糕将被吃掉,哪里会被吃掉!

这个悲伤的故事以丑陋的事实告终:要隐藏Android键盘,您需要提供两种形式的识别: Context以及ViewWindow

我已经创建了一个静态实用程序方法,只要你从一个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或focusable控件。 由此可见,InputMethod(通常是软键盘)将通过显示自身来响应焦点事件。 AndroidManifest.xmlwindowSoftInputMode属性设置为stateAlwaysHidden ,指示键盘忽略此自动分配的初始焦点。

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

几乎令人难以置信的是,当您触摸控件时,似乎无法阻止键盘打开(除非将focusable="false"和/或focusableInTouchMode="false"分配给控件)。 显然,windowSoftInputMode设置仅适用于自动焦点事件,而不适用于触发触摸事件触发的事件。

因此, stateAlwaysHidden名字确实非常糟糕。 它也许应该被称为ignoreInitialFocus

希望这可以帮助。

更新:获取窗口令牌的更多方法

如果没有焦点视图(例如,如果你刚刚更改了片段就会发生),还有其他视图将提供有用的窗口令牌。

if (view == null) view = new View(activity);这些是上述代码的替代品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();

edittext隐藏键盘 windows关闭软键盘

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

在编辑字段中写入并单击Button ,我想隐藏虚拟键盘。 我假设这是一段简单的代码,但我在哪里可以找到它的一个例子?




隐藏软键盘也很有用:

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

这可用于在用户实际触摸editText视图之前抑制软键盘。




Meier的解决方案也适用于我。 在我的情况下,我的应用程序的顶级是tabHost,我想在切换标签时隐藏关键字 - 我从tabHost视图中获取窗口标记。

tabHost.setOnTabChangedListener(new OnTabChangeListener() {
    public void onTabChanged(String tabId) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(tabHost.getApplicationWindowToken(), 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);



如果这里的所有其他答案对您不起作用,那么还有另一种手动控制键盘的方法。

用它来创建一个函数来管理一些EditText的属性:

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

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

然后,确保您打开/关闭键盘的EditText 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);



从搜索到这里,我找到了一个适合我的答案

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



这应该工作:

public class KeyBoard {

    public static void show(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY); // show
    }

    public static void hide(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        imm.toggleSoftInput(InputMethodManager.HIDE_IMPLICIT_ONLY, 0); // hide
    }

    public static void toggle(Activity activity){
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
        if (imm.isActive()){
            hide(activity); 
        } else {
            show(activity); 
        }
    }
}

KeyBoard.toggle(activity);



public void setKeyboardVisibility(boolean show) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    if(show){
        imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
    }else{
        imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(),0);
    }
}



或者到这一切它的解决方案,如果你想关闭软键盘从任何地方,而不必是用于打开键盘(EditText上)字段的引用,但仍然希望这样做,如果该领域的重点,你可以使用这(来自一项活动):

if (getCurrentFocus() != null) {
    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(getCurrentFocus().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();
}



以下是你在Mono for Android(AKA MonoDroid)中的表现

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



添加到您android:windowSoftInputMode="stateHidden"在Manifest文件中的活动。例:

<activity
            android:name=".ui.activity.MainActivity"
            android:label="@string/mainactivity"
            android:windowSoftInputMode="stateHidden"/>



对于我的情况,我在操作栏中使用了SearchView。用户执行搜索后,键盘将再次弹出。

使用InputMethodManager没有关闭键盘。我不得不clearFocus并将搜索视图的焦点设置为false:

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



在某些情况下,除其他所有方法外,此方法都可以使用 这节省了我的一天:)

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



只需在您的活动中使用此优化代码:

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



Related