Android:如何防止软键盘将我的视图向上推?

487

我在应用程序底部有一个垂直滑动抽屉。当软键盘打开时,它会将抽屉的选项卡向上推,使其位于键盘顶部。实际上,我希望它保持在屏幕底部,并在显示键盘时隐藏。

还有其他人遇到这个问题吗?知道如何解决吗?


1
嗨,我遇到了相同的问题,你在清单文件中使用了哪个标志?你能帮我解决一下吗? - Nixit Patel
1
这个问题在这里已经有了重复:https://dev59.com/W2035IYBdhLWcg3wSN4G - WonderWorker
29个回答

781

你可以在AndroidMainfest.xml文件中的你的活动标签内,简单地将你的Activity的windowSoftInputMode标记切换为adjustPan

请查看官方文档获取更多信息。

<activity
   ...
   android:windowSoftInputMode="adjustPan"> 
</activity>

如果您的容器大小不变,则很可能将高度设置为“匹配父项”。如果可能,请将父项设置为“自适应内容”,或者使用约束布局,并将其约束到父项的顶部和底部。

父容器将缩小以适应可用空间,因此您的内容很可能应该放在一个滚动视图中,以避免(根据手机制造商和选择的布局而定...)

  1. 内容被挤压在一起
  2. 内容超出屏幕范围
  3. 由于位于键盘下方而无法访问内容

即使它所在的布局是相对布局或约束布局,内容也可能出现1-3号问题。


61
我不想让视图移动,我希望它保持静态,只需让键盘覆盖它要覆盖的内容。 - Christopher Perry
5
平移指的是滚动视图以使您正在输入的视图可见。换句话说,如果刚出现的键盘没有遮挡焦点视图,那么该视图将保持静态。 - Alexander Oleynikov
19
我也遇到了同样的问题。我在manifest文件中将windowSoftInputMode标志设置为“adjustPan”,但没有起作用。请问如何解决? - Subrat
24
无论windowSoftInputMode的值是什么,在我屏幕底部有一排按钮和上面有一个ScrollView的情况下,它都没有帮助,按钮会被推上去。 - Artem Russakovskii
4
在片段中如何解决“not working in a fragment”的问题?(注意:这是已经翻译过后的结果,不包含解释或额外信息。) - Prashanth Debbadwar
显示剩余9条评论

240

我尝试了所有的解答都不行,但这个方法可以,只需在你的 AndroidManifest.xml 文件中的activity标签中添加此属性:

<activity
     ...
   android:windowSoftInputMode="adjustNothing"> 
</activity>

7
这将使键盘出现在内容的上方,而不会导致布局重新计算其高度。 - Reinherd
27
这解决了键盘推动内容上移的问题,这也是我和原帖作者想要实现的。 - Daniel Douglas
8
您可以借鉴@Dom的方法,使用 getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); 编程设置此值。 - Bron Davies
1
这个对我有效,不像其他答案(果冻豆4.1)。 - Virus721
1
太好了!在我的情况下也有效。我正在显示一个包含EditText的对话框。一旦对话框打开,键盘也会出现。我尝试过“adjustPan”,但它阻止了键盘出现的功能。因此,“adjustNothing”在我的情况下效果更好。 - sembozdemir
显示剩余5条评论

96

在我的情况下,按钮被推上去的原因是因为它们上方的视图是一个 ScrollView,而且无论我设置的 android:windowSoftInputMode 的值是什么,它都会随着键盘折叠而将按钮推到键盘上面。

我能够通过在按钮上方的 ScrollView 上设置 android:isScrollContainer="false" 来避免底部按钮被软键盘推上去。


4
但在这种情况下,软键盘覆盖了屏幕的一部分,没有办法向下滚动。看起来只有一个方法可以防止底部面板出现在键盘顶部 - 在键盘打开时隐藏它... 翻译后: 然而,在这种情况下,软键盘会遮挡部分屏幕,无法向下滚动。似乎唯一的方法是在键盘打开时隐藏底部面板,以防止其出现在键盘顶部... - Dmitry
1
这个设置在我看来非常有趣,因为这是我发现实现"adjustNothing"缺少特性效果的唯一方法! - rupps
提醒大家,这也适用于包含滚动行为的元素,例如listview - Ruchir Baronia
只是想补充一下,对于 WebViews,除了 android:isScrollContainer="false" 之外,您还需要添加 android:windowSoftInputMode="adjustPan"> - GuilhE

91

您可以尝试通过动态添加该属性,将以下代码放置在您的活动的 onCreate 方法中:

您可以在活动的 onCreate 方法中尝试动态添加此属性:

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

这个对我有效,但是那个不行:

android:windowSoftInputMode="adjustPan"

没有。


不需要,因为第一行代码已经完成了任务。 :) @HabeebPerwad - Dom
我在AndoidManifest.xml文件中添加了第二行。我认为只有这样才能使它工作。所以我只是问问。 - Mohammed H
2
@Dom,如何在片段中使用“getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);”? - Tushar Gogna
@TusharGogna 我只在同时存在 Activity 和 Fragment 类的类中使用过,所以我在 Activity 类的 onCreate() 方法中使用了这种方法。如果我找到在 Fragment 中如何做到这一点的方法,我会告诉你的。 - Dom
1
终于!这个可行了!我有一个控制器(扩展自FragmentActivity),并且有一些附加在上面的视图(这些视图扩展自RelativeLayout)。所以在有问题的视图中,我像你说的那样做了controller.getWindow()...。可行了。 - Alaa M.
显示剩余2条评论

47

这里的回答没有帮助到我,所以我尝试了以下方法:

android:windowSoftInputMode="adjustResize"

这个方法非常有效,现在我的应用程序标题不会消失了。使用起来更加流畅。


这对我来说几乎完美地运作了。唯一的问题是键盘的建议栏/行仍然遮挡着我的布局。你遇到过这样的问题吗? - Sufian
1
对于那些可能遇到类似问题的人来说,这可能是由于TabLayout引起的。一旦我将其可见性设置为View.GONE,问题就解决了。也许现在是重新设计我的布局的时候了。 - Sufian
这个可以在不重叠嵌套滚动视图底部按钮的情况下工作。然而,“adjustPan”会重叠底部按钮。 - Hoang Thinh

14

要在片段中以编程方式完成此操作,您可以使用以下代码:

getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);

将其放置在onResume()中


13
这个对我有效。
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

11

针对未来读者。

我希望对这个问题有特定的控制,所以我做了以下操作:

在片段或活动中,隐藏其他不需要的视图(在键盘弹起时不需要显示),然后恢复它们以解决此问题:

            rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    Rect r = new Rect();
                    rootView.getWindowVisibleDisplayFrame(r);
                    int heightDiff = rootView.getRootView().getHeight() - (r.bottom - r.top);

                    if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
                    //ok now we know the keyboard is up...
                        view_one.setVisibility(View.GONE);
                        view_two.setVisibility(View.GONE);

                    }else{
                    //ok now we know the keyboard is down...
                        view_one.setVisibility(View.VISIBLE);
                        view_two.setVisibility(View.VISIBLE);

                    }
                }
            });

1
@Skynet 你说得完全正确!这是我为自己的问题使用的定制解决方案。 - Petro
8
嗨,这太棒了。但是,当键盘关闭时,存在一个短暂的时间(毫秒级别),在这段时间内视图会切换为可见状态。所以,我没有直接设置可见性,而是使用了 view.post(Runnable runnable),然后从那里设置可见性。对我来说效果非常好。 - daisura99
1
@Andrew 我转向了Flutter,感觉非常开心,而且代码也更加清晰。 - Petro
1
是的,这将是我最后一个安卓项目。之后我要转向iOS或干脆停止开发应用程序。太可怕了。 - Andrew
1
@Andrew Adobe XD有一个导出到Flutter的功能,你可以试试看...可能会让你的生活更轻松。 - Petro

11

只需添加一行...

在您的清单文件(manifest file)中的需要添加该属性android:windowSoftInputMode="stateHidden|adjustPan"的活动(activity)。

问题已解决 :) :)


9

对于Xamarin用户,请将以下代码添加到MainActivity类的Activity属性中:

WindowSoftInputMode =Android.Views.SoftInput.AdjustNothing

或者您可以将此代码Window.SetSoftInputMode(Android.Views.SoftInput.AdjustNothing)添加到MainActivity类的OnCreate方法中。

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