Skip to content

Commit 83362d2

Browse files
authored
Update WebViewJNI.java for Android (#33)
* Update WebViewJNI.java * Update WebViewJNI.java * Update WebViewJNI.java * Update WebViewJNI.java * Update WebViewJNI.java Better systemUiVisibility flags for API level < 30 * Update WebViewJNI.java Use `LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES` as in DefoldActivity * Sync with Defold config * Fix navigation bar visible briefly when hiding/showing This happened with immersive mode
1 parent fc30289 commit 83362d2

File tree

2 files changed

+51
-71
lines changed

2 files changed

+51
-71
lines changed

webview/src/java/com/defold/webview/WebViewJNI.java

Lines changed: 46 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import android.view.ViewGroup.MarginLayoutParams;
1616
import android.view.Window;
1717
import android.view.WindowManager;
18+
import android.view.WindowInsets;
19+
import android.view.WindowInsetsController;
1820
import android.widget.LinearLayout;
1921
import android.webkit.ConsoleMessage;
2022
import android.webkit.JavascriptInterface;
@@ -34,66 +36,15 @@ public class WebViewJNI {
3436

3537
private Activity activity;
3638
private static WebViewInfo[] infos;
39+
private boolean immersiveMode = false;
40+
private boolean displayCutout = false;
3741

3842
public native void onPageLoading(String url, int webview_id, int request_id);
3943
public native void onPageFinished(String url, int webview_id, int request_id);
4044
public native void onReceivedError(String url, int webview_id, int request_id, String errorMessage);
4145
public native void onEvalFinished(String result, int webview_id, int request_id);
4246
public native void onEvalFailed(String errorMessage, int webview_id, int request_id);
4347

44-
private static class CustomWebView extends WebView {
45-
private WebViewInfo info;
46-
47-
public CustomWebView(Activity context, WebViewInfo info) {
48-
super(context);
49-
this.info = info;
50-
}
51-
52-
// For Android 2.3 able to show Keyboard on input / textarea focus
53-
@Override
54-
public boolean onTouchEvent(MotionEvent event) {
55-
switch (event.getAction()) {
56-
case MotionEvent.ACTION_DOWN:
57-
case MotionEvent.ACTION_UP:
58-
if (!this.hasFocus()) {
59-
this.requestFocus();
60-
61-
}
62-
63-
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) { // Api level 11
64-
setSystemUiVisibility(
65-
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
66-
//| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
67-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
68-
//| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
69-
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
70-
| View.SYSTEM_UI_FLAG_IMMERSIVE
71-
);
72-
invalidate();
73-
}
74-
break;
75-
}
76-
return super.onTouchEvent(event);
77-
}
78-
79-
@Override
80-
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
81-
super.onLayout(changed, left, top, right, bottom);
82-
83-
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) { // Api level 11
84-
setSystemUiVisibility(
85-
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
86-
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
87-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
88-
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
89-
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
90-
| View.SYSTEM_UI_FLAG_IMMERSIVE
91-
);
92-
invalidate();
93-
}
94-
}
95-
}
96-
9748
private static class CustomWebViewClient extends WebViewClient {
9849
public Activity activity;
9950
public int webviewID;
@@ -238,7 +189,7 @@ public boolean onConsoleMessage(ConsoleMessage msg) {
238189

239190
private class WebViewInfo
240191
{
241-
CustomWebView webview;
192+
WebView webview;
242193
CustomWebViewClient webviewClient;
243194
CustomWebChromeClient webviewChromeClient;
244195
LinearLayout layout;
@@ -247,29 +198,20 @@ private class WebViewInfo
247198
int webviewID;
248199
};
249200

250-
public WebViewJNI(Activity activity, int maxnumviews) {
201+
public WebViewJNI(Activity activity, int maxnumviews, boolean immersiveMode, boolean displayCutout) {
251202
this.activity = activity;
252203
this.infos = new WebViewInfo[maxnumviews];
204+
this.immersiveMode = immersiveMode;
205+
this.displayCutout = displayCutout;
253206
}
254207

255208
private WebViewInfo createView(Activity activity, int webview_id)
256209
{
257210
WebViewInfo info = new WebViewInfo();
258211
info.webviewID = webview_id;
259-
info.webview = new CustomWebView(activity, info);
212+
info.webview = new WebView(activity);
260213
info.webview.setVisibility(View.GONE);
261214

262-
if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) { // Api level 11
263-
info.webview.setSystemUiVisibility(
264-
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
265-
//| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
266-
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
267-
//| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
268-
| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
269-
| View.SYSTEM_UI_FLAG_IMMERSIVE
270-
);
271-
}
272-
273215
MarginLayoutParams params = new MarginLayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT);
274216
params.setMargins(0, 0, 0, 0);
275217

@@ -308,7 +250,28 @@ private WebViewInfo createView(Activity activity, int webview_id)
308250
info.windowParams.y = WindowManager.LayoutParams.MATCH_PARENT;
309251
info.windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
310252
info.windowParams.height = WindowManager.LayoutParams.MATCH_PARENT;
311-
info.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
253+
info.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; // Fix navigation bar visible briefly when hiding/showing
254+
info.windowParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING;
255+
if (Build.VERSION.SDK_INT < 30) {
256+
if (immersiveMode) {
257+
info.windowParams.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
258+
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
259+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
260+
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
261+
| View.SYSTEM_UI_FLAG_FULLSCREEN
262+
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
263+
} else {
264+
info.windowParams.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
265+
// | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
266+
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
267+
// | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
268+
| View.SYSTEM_UI_FLAG_FULLSCREEN
269+
| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
270+
}
271+
}
272+
if (displayCutout && Build.VERSION.SDK_INT >= 28) {
273+
info.windowParams.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES;
274+
}
312275

313276
info.layout.setLayoutParams(info.windowParams);
314277
return info;
@@ -323,6 +286,20 @@ private void setVisibleInternal(WebViewInfo info, int visible)
323286
info.first = 0;
324287
WindowManager wm = activity.getWindowManager();
325288
wm.addView(info.layout, info.windowParams);
289+
290+
// Fix navigation bar visible briefly when hiding/showing
291+
info.windowParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
292+
wm.updateViewLayout(info.layout, info.windowParams);
293+
294+
if (Build.VERSION.SDK_INT >= 30) {
295+
WindowInsetsController windowInsetsController = info.layout.getWindowInsetsController();
296+
windowInsetsController.setSystemBarsBehavior(WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE);
297+
if (immersiveMode) {
298+
windowInsetsController.hide(WindowInsets.Type.systemBars());
299+
} else {
300+
windowInsetsController.hide(WindowInsets.Type.statusBars());
301+
}
302+
}
326303
}
327304
}
328305

@@ -333,7 +310,7 @@ private void setPositionInternal(WebViewInfo info, int x, int y, int width, int
333310
info.windowParams.width = width >= 0 ? width : WindowManager.LayoutParams.MATCH_PARENT;
334311
info.windowParams.height = height >= 0 ? height : WindowManager.LayoutParams.MATCH_PARENT;
335312

336-
if (info.webview.getVisibility() == View.VISIBLE ) {
313+
if (info.webview.getVisibility() == View.VISIBLE) {
337314
WindowManager wm = activity.getWindowManager();
338315
wm.updateViewLayout(info.layout, info.windowParams);
339316
}

webview/src/webview_android.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include <dmsdk/dlib/array.h>
88
#include <dmsdk/dlib/log.h>
99
#include <dmsdk/dlib/mutex.h>
10+
#include <dmsdk/dlib/configfile.h>
1011
#include <dmsdk/script/script.h>
1112
#include <dmsdk/extension/extension.h>
1213
#include <android_native_app_glue.h>
@@ -390,8 +391,10 @@ dmExtension::Result Platform_AppInitialize(dmExtension::AppParams* params)
390391
g_WebView.m_IsVisible = env->GetMethodID(webview_class, "isVisible", "(I)I");
391392
g_WebView.m_SetPosition = env->GetMethodID(webview_class, "setPosition", "(IIIII)V");
392393

393-
jmethodID jni_constructor = env->GetMethodID(webview_class, "<init>", "(Landroid/app/Activity;I)V");
394-
g_WebView.m_WebViewJNI = env->NewGlobalRef(env->NewObject(webview_class, jni_constructor, threadAttacher.GetActivity()->clazz, dmWebView::MAX_NUM_WEBVIEWS));
394+
int32_t immersiveMode = dmConfigFile::GetInt(params->m_ConfigFile, "android.immersive_mode", 0);
395+
int32_t displayCutout = dmConfigFile::GetInt(params->m_ConfigFile, "android.display_cutout", 1);
396+
jmethodID jni_constructor = env->GetMethodID(webview_class, "<init>", "(Landroid/app/Activity;IZZ)V");
397+
g_WebView.m_WebViewJNI = env->NewGlobalRef(env->NewObject(webview_class, jni_constructor, threadAttacher.GetActivity()->clazz, dmWebView::MAX_NUM_WEBVIEWS, immersiveMode == 1, displayCutout == 1));
395398

396399
return dmExtension::RESULT_OK;
397400
}

0 commit comments

Comments
 (0)