Skip to content

Commit 9f6fa7a

Browse files
committed
apache#110 (Android) Fixed keyboard from overlapping content
1 parent d4dcd71 commit 9f6fa7a

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

plugin.xml

+1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838

3939
<platform name="android">
4040
<source-file src="src/android/StatusBar.java" target-dir="src/org/apache/cordova/statusbar" />
41+
<source-file src="src/android/StatusBarViewHelper.java" target-dir="src/org/apache/cordova/statusbar" />
4142

4243
<config-file target="res/xml/config.xml" parent="/*">
4344
<feature name="StatusBar">

src/android/StatusBar.java

+12
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040

4141
public class StatusBar extends CordovaPlugin {
4242
private static final String TAG = "StatusBar";
43+
private boolean _isVisible = true;
4344

4445
private static final String ACTION_HIDE = "hide";
4546
private static final String ACTION_SHOW = "show";
@@ -66,11 +67,16 @@ public class StatusBar extends CordovaPlugin {
6667
public void initialize(final CordovaInterface cordova, CordovaWebView webView) {
6768
LOG.v(TAG, "StatusBar: initialization");
6869
super.initialize(cordova, webView);
70+
StatusBar statusbar = this;
6971

7072
activity = this.cordova.getActivity();
7173
window = activity.getWindow();
7274

7375
activity.runOnUiThread(() -> {
76+
//https://github.com/apache/cordova-plugin-statusbar/issues/110
77+
//This corrects keyboard behaviour when overlaysWebView is true
78+
StatusBarViewHelper.assist(cordova.getActivity(), statusbar);
79+
7480
// Clear flag FLAG_FORCE_NOT_FULLSCREEN which is set initially
7581
// by the Cordova.
7682
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
@@ -88,6 +94,10 @@ public void initialize(final CordovaInterface cordova, CordovaWebView webView) {
8894
});
8995
}
9096

97+
public boolean isVisible() {
98+
return _isVisible;
99+
}
100+
91101
/**
92102
* Executes the request and returns PluginResult.
93103
*
@@ -117,6 +127,7 @@ public boolean execute(final String action, final CordovaArgs args, final Callba
117127
// CB-11197 We still need to update LayoutParams to force status bar
118128
// to be hidden when entering e.g. text fields
119129
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
130+
_isVisible = true;
120131
});
121132
return true;
122133

@@ -131,6 +142,7 @@ public boolean execute(final String action, final CordovaArgs args, final Callba
131142
// CB-11197 We still need to update LayoutParams to force status bar
132143
// to be hidden when entering e.g. text fields
133144
window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
145+
_isVisible = false;
134146
});
135147
return true;
136148

src/android/StatusBarViewHelper.java

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package org.apache.cordova.statusbar;
2+
3+
import android.app.Activity;
4+
import android.graphics.Rect;
5+
import android.view.View;
6+
import android.view.ViewTreeObserver;
7+
import android.widget.FrameLayout;
8+
9+
public class StatusBarViewHelper {
10+
11+
// For more information, see https://issuetracker.google.com/issues/36911528
12+
// To use this class, simply invoke assistActivity() on an Activity that already has its content view set.
13+
14+
//This solution was based off of
15+
//https://stackoverflow.com/questions/7417123/android-how-to-adjust-layout-in-full-screen-mode-when-softkeyboard-is-visible/19494006#answer-42261118
16+
17+
private View mChildOfContent;
18+
private int usableHeightPrevious;
19+
private FrameLayout.LayoutParams frameLayoutParams;
20+
private Activity activity;
21+
private StatusBar statusbar;
22+
private static final String TAG = "StatusBarViewHelper";
23+
24+
static void assist(Activity activity, StatusBar statusbar) {
25+
new StatusBarViewHelper(activity, statusbar);
26+
}
27+
28+
private StatusBarViewHelper(Activity a, StatusBar b) {
29+
activity = a;
30+
statusbar = b;
31+
32+
FrameLayout content = (FrameLayout) activity.findViewById(android.R.id.content);
33+
mChildOfContent = content.getChildAt(0);
34+
35+
mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
36+
public void onGlobalLayout() {
37+
possiblyResizeChildOfContent();
38+
}
39+
});
40+
41+
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
42+
}
43+
44+
private void possiblyResizeChildOfContent() {
45+
int usableHeightNow = computeUsableHeight();
46+
if (usableHeightNow != usableHeightPrevious) {
47+
frameLayoutParams.height = usableHeightNow;
48+
mChildOfContent.requestLayout();
49+
usableHeightPrevious = usableHeightNow;
50+
}
51+
}
52+
53+
private boolean _isStatusBarVisible() {
54+
return statusbar.isVisible();
55+
}
56+
57+
private int computeUsableHeight() {
58+
Rect r = new Rect();
59+
mChildOfContent.getWindowVisibleDisplayFrame(r);
60+
int uiOptions = activity.getWindow().getDecorView().getSystemUiVisibility();
61+
boolean isFullscreen = ((uiOptions | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) == uiOptions);
62+
boolean isStatusBarVisible = this._isStatusBarVisible();
63+
64+
int usableHeight = r.bottom;
65+
66+
// This handles both overlayed status bars and reserved spaces for cutouts when the
67+
// status bar is hidden
68+
if (!isFullscreen || (isFullscreen && !isStatusBarVisible)) {
69+
usableHeight = usableHeight - r.top;
70+
}
71+
72+
return usableHeight;
73+
}
74+
}

0 commit comments

Comments
 (0)