Android键盘覆盖视图,但仅在全屏模式下

vshtjzan  于 2023-01-19  发布在  Android
关注(0)|答案(2)|浏览(134)

我有简单的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,不同的布局,在运行时更改为全屏,滚动视图),但没有任何效果。

3pvhb19x

3pvhb19x1#

*调整调整大小

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>

活动_主要.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>

主要活动.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, "");
    }

}

样式.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>

输出屏幕:

mlnl4t2r

mlnl4t2r2#

对于可组合组件,解决方案是在父组件上使用imePadding。例如,如果您的AndroidView位于Box中,则:

Box(Modifier.imePadding()) {
      AndroidView(factory = {
            WebView(this).apply {
                webViewClient = WebViewClient()
                loadUrl("https://example.com")
            }
        })
   }

相关问题