2

I have simple android app with relative layout and webview in it:

<?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>

The page displayed in webview is:

<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>

This is how it looks like when I enters the text input. Webview is resized as keyboard appears. Everything work as expected. No problem.

Working version

Now I want to make the app fullscreen. I change styles.xml like this:

<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>

The app is now fullscreen. But when I tap input it is covered by soft keyboard and I cannot see what I'm typing.

enter image description here

I've tried everything (android:windowSoftInputMode="adjustResize", adjustPan, different layouts, changing to fullscreen in runtime, scrollview) but nothing worked.

Community
  • 1
  • 1
asdjfiasd
  • 1,572
  • 15
  • 28
  • AFAIK, android's keyboard pushes the UI up while iOS overlays over the UI. This was a problem I faced before and wasn't able to find a fix to it unfortunately. – rmanalo Aug 23 '19 at 09:32
  • Refer this link you will definitely find something useful https://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible – Rohan Aug 23 '19 at 10:08

2 Answers2

2
  • adjustResize

The activity's main window is always resized to make room for the soft keyboard on screen.

But it has limitations when your application is in fullscreen mode. Android official documentation says:

If the window's layout parameter flags include FLAG_FULLSCREEN, this value for softInputMode will be ignored; the window will not resize, but will stay fullscreen.

Check for more info:doc

Retrieve the overall visible display size in which the window this view is attached to has been positioned in. This takes into account screen decorations above the window, for both cases where the window itself is being position inside of them or the window is being placed under then and covered insets are used for the window to position its content inside. In effect, this tells you the available area where content can be placed and remain visible to users.

So,We need to detect when keyboard open and hide and calculate its size as per view.Below is example code.

Example code:

Manifest:

<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>

Output screen:

enter image description here

Kabir
  • 852
  • 7
  • 11
  • It works. But it looks kinda fragile. Is it reliable across different android versions? – asdjfiasd Aug 24 '19 at 14:56
  • I checked this code in android Oreo(Motorola device),android nougat(Nokia) and Redmi 3s.Its work completely fine. – Kabir Aug 24 '19 at 15:31
  • I have checked lots of reference of full screen with adjustResize attribute and also implement those.Best method is this to detect keyboard open and calculate size and adjust your layout.Its reliable across different version of android system. – Kabir Sep 04 '19 at 09:18
0

For composables the solution would be to use imePadding on the parent component. For example if your AndroidView is in a Box then:

   Box(Modifier.imePadding()) {
      AndroidView(factory = {
            WebView(this).apply {
                webViewClient = WebViewClient()
                loadUrl("https://example.com")
            }
        })
   }
Ketan sangle
  • 376
  • 5
  • 6