【问题标题】:Android keyboard covers the view but only in fullscreen modeAndroid键盘覆盖视图,但仅在全屏模式下
【发布时间】:2019-08-23 07:56:16
【问题描述】:

我有一个简单的 android 应用程序,其中包含相对布局和 webview:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <WebView
        android:id="@+id/MyWebView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

webview中显示的页面是:

<html>
    <body style="padding: 0; margin: 0; box-sizing: border-box; border: 5px solid red; width: 100vw; height: 100vh;">
    test
    <div style="width: 50vw; height: 70vh; border: 1px solid green;">some div</div>
    <input placeholder="Type here and KB will cover this">
    </body>
</html>

这是我输入文本输入时的样子。 Webview 会随着键盘的出现而调整大小。一切都按预期工作。没问题。

现在我想让应用全屏显示。我像这样更改styles.xml:

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowFullscreen">true</item>
    </style>

应用程序现在是全屏的。但是当我点击输入时,它被软键盘覆盖,我看不到我在输入什么。

我已经尝试了所有方法(android:windowSoftInputMode="adjustResize"、adjustPan、不同的布局、在运行时更改为全屏、滚动视图)但没有任何效果。

【问题讨论】:

  • AFAIK,android 的键盘将 UI 向上推,而 iOS 覆盖在 UI 上。这是我之前遇到的问题,很遗憾无法找到解决方法。
  • 参考这个链接你一定会找到有用的stackoverflow.com/questions/7417123/…

标签: android android-studio


【解决方案1】:
  • 调整大小

Activity 的主窗口总是会调整大小,以便为软体腾出空间 屏幕上的键盘。

但是当您的应用程序处于全屏模式时,它会受到限制。 Android官方文档说:

如果窗口的布局参数标志包括 FLAG_FULLSCREEN,这 softInputMode 的值将被忽略;窗口不会调整大小, 但会保持全屏显示。

查看更多信息:doc

检索此窗口所在的整体可见显示大小 视图附加到已定位。这考虑到 窗口上方的屏幕装饰,适用于窗口 本身正在它们内部或正在放置窗口 然后和覆盖的插图用于窗口定位其 里面的内容。实际上,这会告诉您可用区域 内容可以放置并保持对用户可见。

所以,我们需要检测键盘何时打开和隐藏,并根据视图计算其大小。下面是示例代码。

示例代码:

清单:

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    tools:ignore="GoogleAppIndexingWarning">

    <activity android:name=".MainActivity"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

activity_main.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:fitsSystemWindows="true"
    android:id="@+id/frame"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <WebView
        android:id="@+id/MyWebView1"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</RelativeLayout>

MainActivity.java

 public class MainActivity extends AppCompatActivity {
    WebView webView;
    RelativeLayout relativeLayout;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
        getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
        setContentView(R.layout.activity_main);
        relativeLayout=findViewById(R.id.frame);
        webView=findViewById(R.id.MyWebView1);
        this.getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                Rect r = new Rect();
                getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
                int height = relativeLayout.getContext().getResources().getDisplayMetrics().heightPixels;
                int diff = height - r.bottom;
                if (diff != 0) {
                    if (relativeLayout.getPaddingBottom() != diff) {
                        relativeLayout.setPadding(0, 0, 0, diff);
                    }
                } else {
                    if (relativeLayout.getPaddingBottom() != 0) {
                        relativeLayout.setPadding(0, 0, 0, 0);
                    }
                }
            }
        });
        final String mimeType = "text/html";
        final String encoding = "UTF-8";
        String html = "<html>\n" +
                "    <body style=\"padding: 0; margin: 0; box-sizing: border-box; border: 5px solid red; width: 100vw; height: 100vh;\">\n" +
                "    test\n" +
                "    <div style=\"width: 50vw; height: 70vh; border: 1px solid green;\">some div</div>\n" +
                "    <input placeholder=\"Type here and KB will cover this\">\n" +
                "    </body>\n" +
                "</html>";
        webView.loadDataWithBaseURL("", html, mimeType, encoding, "");
    }

}

styles.xml:

<resources xmlns:tools="http://schemas.android.com/tools">

    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

</resources>

输出画面:

【讨论】:

  • 它有效。但它看起来有点脆弱。跨不同的安卓版本是否可靠?
  • 我在 android Oreo(Motorola device)、android nougat(Nokia) 和 Redmi 3s 中检查了这段代码。它工作得很好。
  • 我已经检查了很多关于全屏的参考,并使用了 adjustResize 属性并实现了这些。最好的方法是检测键盘打开并计算大小并调整布局。它在不同版本的 android 系统中都是可靠的。
猜你喜欢
  • 1970-01-01
  • 2013-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
  • 1970-01-01
  • 2012-12-03
相关资源
最近更新 更多