导航抽屉打开时如何隐藏键盘

24

我有一个包含EditText的碎片。当我点击EditText时,键盘弹出。问题是当我打开抽屉时,抽屉不能隐藏键盘。即使我切换到另一个碎片,键盘仍然显示。如何在打开抽屉时隐藏键盘。

我尝试过放置

InputMethodManager imm = 
                        (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getWindowToken(), 0);

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

两者都不会隐藏键盘。

7个回答

32

在打开/关闭抽屉式导航菜单前,使用以下代码行:

InputMethodManager inputMethodManager = (InputMethodManager)  this.getSystemService(Activity.INPUT_METHOD_SERVICE);
    inputMethodManager.hideSoftInputFromWindow(this.getCurrentFocus().getWindowToken(), 0);

我在使用Fragments(位于NavigationDrawerViewPager中)时,经常遇到从EditText获取WindowToken的问题。我所缺少的是Activity.getCurrentFocus()。非常感谢。 - shkschneider
同意。在DrawerListener中使用其他hideKeyboard()方法,再结合某种形式的焦点调整,仍然会在打开NavDrawer时显示键盘。这是我唯一尝试成功的变化。它基本上结合了我之前分别尝试但未成功的努力。 - Xijukx

28

试试这个...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ......
   
    //Initialize
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
   
    //Setting the actionbarToggle to drawer layout
    drawerLayout.setDrawerListener(actionBarDrawerToggle);

    //calling sync state is necessay or else your hamburger icon wont show up
    actionBarDrawerToggle.syncState();

}

DrawerListerner


 ActionBarDrawerToggle actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawerLayout, toolbar, R.string.app_name, R.string.app_name) {

        @Override
        public void onDrawerClosed(View drawerView) {
            // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
            super.onDrawerClosed(drawerView);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
            super.onDrawerOpened(drawerView);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
    };

您好,我遇到了一个空指针异常。代码如下:if (drawer != null) { drawer.setDrawerListener(toggle); hideKeyboard(this); } 我无法在使用appcompatv7的Android Studio中更改ActionBarDrawerToggle。请帮忙解决。 - Pihu
请检查您的ActionBarDrawerToggle监听器对象,如果没有正确实现,可能会引起空指针异常。 - Silambarasan Poonguti

9

抽屉式导航监听器已过时,您可以使用mDrawerLayout.addDrawerListener()来检测导航抽屉状态变化,并在onDrawerStateChange中关闭键盘。

mDrawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {

    @Override
    public void onDrawerSlide(View drawerView, float slideOffset) {
        //Called when a drawer's position changes.

    }

    @Override
    public void onDrawerOpened(View drawerView) {
        //Called when a drawer has settled in a completely open state.
        //The drawer is interactive at this point.
        // If you have 2 drawers (left and right) you can distinguish 
        // them by using id of the drawerView. int id = drawerView.getId(); 
        // id will be your layout's id: for example R.id.left_drawer            
    }

    @Override
    public void onDrawerClosed(View drawerView) {
        // Called when a drawer has settled in a completely closed state.
    }

    @Override
    public void onDrawerStateChanged(int newState) {
        // Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
        InputMethodManager inputMethodManager = (InputMethodManager)
                getSystemService(Context.INPUT_METHOD_SERVICE);
        inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

    }
});  

1
我创建了自己的Helper类来显示或隐藏键盘。
这是代码...
public static class Helper {

    public static void showKeyboard(Activity activity) {
        InputMethodManager imm = (InputMethodManager) activity.getSystemService(Context.INPUT_METHOD_SERVICE);
        if (imm != null) {
            imm.showSoftInput(activity.getCurrentFocus(), InputMethodManager.SHOW_IMPLICIT);
        }
    }

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

}

调用Helper.showKeyboard(this)来显示键盘。 调用Helper.hideKeyboard(this)来隐藏键盘。 this指的是Activity。


1
问题在于必须从当前“持有”键盘的视图中调用getWindowToken()。我同意这很烦人,但这就是它的工作方式。
例如,假设EditText mEditText是当前正在接收键盘按键的焦点对象。那么你的代码将是:
 InputMethodManager imm = 
                    (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);

1
这是我目前想到的最简单的解决方案。你需要创建一个InputMethodManager对象,将监听器添加到DrawerLayout对象中,最后在以下方法中添加一行代码:inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);,然后就可以了。
InputMethodManager inputMethodManager = (InputMethodManager) this.getSystemService(Activity.INPUT_METHOD_SERVICE);

    drawerLayout.addDrawerListener(new DrawerLayout.DrawerListener() {
        @Override
        public void onDrawerSlide(@NonNull View view, float v) {
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
        }
        @Override
        public void onDrawerOpened(@NonNull View view) {
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
        }

        @Override
        public void onDrawerClosed(@NonNull View view) {
            inputMethodManager.hideSoftInputFromWindow(view.getWindowToken(),0);
        }

        @Override
        public void onDrawerStateChanged(int i) {
        }
    });

1
如果您使用了带有抽屉式导航的切换按钮,则需要在onCreate方法中手动添加onDrawerStateChanged。
 DrawerLayout drawer = findViewById(R.id.drawer_layout);
        //ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawer, appToolBar, R.string.Open_Drawer, R.string.Close_Drawer);


        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(this, drawerLayout, appToolBar, R.string.app_name, R.string.app_name) {

            @Override
            public void onDrawerClosed(View drawerView) {
                // Code here will be triggered once the drawer closes as we dont want anything to happen so we leave this blank
                super.onDrawerClosed(drawerView);
               /* InputMethodManager inputMethodManager = (InputMethodManager)  getSystemService(Activity.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        */    }

            @Override
            public void onDrawerOpened(View drawerView) {
                // Code here will be triggered once the drawer open as we dont want anything to happen so we leave this blank
                super.onDrawerOpened(drawerView);
              /*  InputMethodManager inputMethodManager = (InputMethodManager)  getSystemService(Activity.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
       */     }

            @Override
            public void onDrawerStateChanged(int newState) {
                // Called when the drawer motion state changes. The new state will be one of STATE_IDLE, STATE_DRAGGING or STATE_SETTLING.
                InputMethodManager inputMethodManager = (InputMethodManager)
                        getSystemService(Context.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);

            }
        };




        drawer.addDrawerListener(toggle);

        toggle.syncState();

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接