当导航抽屉打开时,我该如何关闭键盘?

9
我已经在我的应用程序中添加了一个导航抽屉。到目前为止,其他一切都很好,但是当导航抽屉打开时,键盘没有关闭。导航抽屉是主要活动,然后从抽屉中打开的每个页面都是片段。
我已经尝试在片段中的每个EditText区域中添加以下内容。但是,这并没有关闭任何东西。
InputMethodManager imm1 = (InputMethodManager)getActivity().getSystemService(
            Context.INPUT_METHOD_SERVICE);
        imm1.hideSoftInputFromWindow(input1.getWindowToken(), 0);

我也尝试将该代码放在主活动中,但同样未能成功。您有什么不同的想法可以让它正常工作吗?
8个回答

15
为了在打开或关闭导航抽屉时隐藏打开的键盘,请重写 onDrawerSlide 方法并在 onDrawerListner 中添加以下行。
InputMethodManager inputMethodManager = (InputMethodManager) actionBarActivity
    .getSystemService(Activity.INPUT_METHOD_SERVICE);
inputMethodManager.hideSoftInputFromWindow(
    actionBarActivity.getCurrentFocus().getWindowToken(),
    0
);

当使用此功能时,片段视图将失去焦点,然后焦点将放在片段的第一个可聚焦视图上,有没有办法避免这种情况呢? 另一个问题是在 onDrawerSlide 方法调用中,此随机显示视图(在我的情况下,是用于提交功能的按钮)将向屏幕上升,就像使用了 android:windowSoftInputMode="adjustResize" 一样。 - chinaanihchen
这是最终让我成功的方法。谢谢。 - blazingwolf

11
final DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle  actionBarDrawerToggle = new ActionBarDrawerToggle(this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
       }

        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }

        @Override
        public void onDrawerSlide(View drawerView, float slideOffset) {
            super.onDrawerSlide(drawerView, slideOffset);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
    };
    drawer.setDrawerListener(actionBarDrawerToggle);
    actionBarDrawerToggle.syncState();

当你滑动打开抽屉或抽屉被打开时,确保将以下代码添加到你的onCreate方法中,以隐藏键盘。此外,在你的onCreate方法中声明你的工具栏也是必要的。 - Gilad Brunfman
对我来说,仅仅覆盖onDrawerOpened()就足够了。 - Antônio Medeiros

4

这对我非常有效:

private ActionBarDrawerToggle aDrawerToggle;
private DrawerLayout aDrawerLayout;

在创建类之后,我在void中使用了以下代码:

        aDrawerToggle = new ActionBarDrawerToggle(getActivity(), 
        aDrawerLayout, 
        R.drawable.main_icon, 
        R.string.drawer_open, 
        R.string.drawer_close){

        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            if (!isAdded()) {
                return;
            }

            InputMethodManager inputMethodManager = (InputMethodManager)getActivity().getSystemService(
                    Context.INPUT_METHOD_SERVICE);


            //inputSearch is my EditText
            inputMethodManager.hideSoftInputFromWindow(inputSearch.getWindowToken(), 0);

            getActivity().supportInvalidateOptionsMenu();
        }
}

3

在您的DrawerLayout中添加DrawerListener。然后,您可以在onDrawerOpened()方法中使用上面的代码来关闭键盘。


感谢您的回答,我很感激您抽出时间。我试着自己设置过,但是我不明白具体的实现方法。您能否给我展示一下它应该如何完成的代码片段?到目前为止,我的搜索都没有什么结果。我一直在使用 Google 版本的抽屉。 - blazingwolf
1
你是否正在使用支持库的DrawerLayout?如果是,只需在xml文件中为DrawerLayout指定一个id,然后通过使用“DrawerLayout mDrawerLayout =(DrawerLayout)findViewById(R.id.myDrawerLayout);”在Activity中获取DrawerLayout的实例。然后您可以像这样实现它:mDrawerLayout.setDrawerListener(new DrawerListener(){... //在此处覆盖方法...}); - dumazy
是的,我正在使用支持库中的 DrawerLayout。但是,显然我戴着我的“蠢蛋”帽子,因为每次我尝试实现你提到的代码时都会出现错误。findViewById 已经设置为 DrawerLayout id,所以我尝试设置新的监听器,这就是错误发生的地方,而且我还会在新的监听器上发生错误(说 new 是无效类型)。我想这只是我做错了一些事情,但如果现在能找出来就太好了。感谢你的所有帮助。 - blazingwolf
好的。最终成功设置了DrawerListener,没有出现错误。:D 但是隐藏键盘仍然存在问题。我的主活动中没有任何编辑文本字段,只有片段才有。因此,我无法说“(EditText.getWindowToken,0);。一旦我删除EditText部分,就会出现一个错误,指出getWindowToken未定义。:/ - blazingwolf
只需编写“ MyActivity activity =(MyActivity)getActivity;'' 然后 ''activity.setTheEditText(someEditText)'',您的活动即可知道该编辑文本框。 - dumazy
显示剩余2条评论

2

在onCreate方法中:

DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawerLayout.setDrawerListener(new DrawerLayout.DrawerListener() {
            @Override
            public void onDrawerSlide(View drawerView, float slideOffset) {
            }

            @Override
            public void onDrawerOpened(View drawerView) {
            }

            @Override
            public void onDrawerClosed(View drawerView) {
            }

            @Override
            public void onDrawerStateChanged(int newState) {
                InputMethodManager imm = (InputMethodManager)getSystemService(Context.
                        INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            }
        });

0
This does not solve issue.
Correct solution is: Override below method on your main activity:

      public boolean dispatchTouchEvent(MotionEvent ev)
    {

        View view = getCurrentFocus();
        boolean ret = super.dispatchTouchEvent(ev);
if(drawer_open) {

//如果滑块打开,则不执行任何操作 } else { if (view instanceof EditText) { View w = getCurrentFocus(); int scrcoords[] = new int[2]; w.getLocationOnScreen(scrcoords); float x = ev.getRawX() + w.getLeft() - scrcoords[0]; float y = ev.getRawY() + w.getTop() - scrcoords[1];

        if (ev.getAction() == MotionEvent.ACTION_UP && (x < w.getLeft() || x >= w.getRight() || y < w.getTop() || y > w.getBottom())) {
            InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.hideSoftInputFromWindow(getWindow().getCurrentFocus().getWindowToken(), 0);
        }
    }

        return ret;

    }

0

尝试使用这段代码,我在我的应用程序中使用它,例如,如果我打开包含EditText的对话框,则在on create中设置此代码。希望这能帮到你。

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


谢谢你的回答,我很感激你抽出时间来回答。但是当我将它添加到我的应用程序中时,它对我没有任何作用,所以我认为我做错了什么。 - blazingwolf

0

由于 drawer.setDrawerListener(toggle) 已被弃用,请使用以下所示的 drawer.addDrawerListener(toggle)

private void initDrawerLayout() {

    drawer = findViewById(R.id.drawer_layout);
    ActionBarDrawerToggle toggle = new ActionBarDrawerToggle
            (this, drawer, toolbar,
                    R.string.navigation_drawer_open,
                    R.string.navigation_drawer_close)
    {
        @Override
        public void onDrawerClosed(View drawerView) {
            super.onDrawerClosed(drawerView);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }

        @Override
        public void onDrawerOpened(View drawerView) {
            super.onDrawerOpened(drawerView);
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
        }
    };
    drawer.addDrawerListener(toggle);
    toggle.syncState();
    drawer.closeDrawer(GravityCompat.START);
}

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