Skip to content

Commit

Permalink
feat(Keyboard): Add resizeOnFullScreen plugin configuration (#627)
Browse files Browse the repository at this point in the history
  • Loading branch information
jcesarmobile committed Sep 22, 2021
1 parent 213ffce commit 8e87836
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 7 deletions.
13 changes: 8 additions & 5 deletions keyboard/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ Keyboard.addListener('keyboardDidHide', () => {

On iOS, the keyboard can be configured with the following options:

| Prop | Type | Description | Default | Since |
| ------------ | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
| **`resize`** | <code><a href="#keyboardresize">KeyboardResize</a></code> | Configure the way the app is resized when the Keyboard appears. Only available on iOS. | <code>native</code> | 1.0.0 |
| **`style`** | <code>'dark' \| 'light'</code> | Override the keyboard style if your app doesn't support dark/light theme changes. If not set, the keyboard style will depend on the device appearance. Only available on iOS. | | 1.0.0 |
| Prop | Type | Description | Default | Since |
| ------------------------ | --------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- | ----- |
| **`resize`** | <code><a href="#keyboardresize">KeyboardResize</a></code> | Configure the way the app is resized when the Keyboard appears. Only available on iOS. | <code>native</code> | 1.0.0 |
| **`style`** | <code>'dark' \| 'light'</code> | Override the keyboard style if your app doesn't support dark/light theme changes. If not set, the keyboard style will depend on the device appearance. Only available on iOS. | | 1.0.0 |
| **`resizeOnFullScreen`** | <code>boolean</code> | There is an Android bug that prevents the keyboard from resizing the WebView when the app is in full screen (i.e. if StatusBar plugin is used to overlay the status bar). This setting, if set to true, add a workaround that resizes the WebView even when the app is in full screen. Only available for Android | | 1.1.0 |

### Examples

Expand All @@ -52,7 +53,8 @@ In `capacitor.config.json`:
"plugins": {
"Keyboard": {
"resize": "body",
"style": "dark"
"style": "dark",
"resizeOnFullScreen": true
}
}
}
Expand All @@ -70,6 +72,7 @@ const config: CapacitorConfig = {
Keyboard: {
resize: "body",
style: "dark",
resizeOnFullScreen: true,
},
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
import android.view.Display;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowInsets;
import android.view.inputmethod.InputMethodManager;
import android.widget.FrameLayout;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;

Expand All @@ -22,6 +24,9 @@ interface KeyboardEventListener {
private AppCompatActivity activity;
private ViewTreeObserver.OnGlobalLayoutListener list;
private View rootView;
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;

@Nullable
public KeyboardEventListener getKeyboardEventListener() {
Expand All @@ -40,7 +45,16 @@ public void setKeyboardEventListener(@Nullable KeyboardEventListener keyboardEve
static final String EVENT_KB_WILL_HIDE = "keyboardWillHide";
static final String EVENT_KB_DID_HIDE = "keyboardDidHide";

/**
* @deprecated
* Use {@link #Keyboard(AppCompatActivity activity, boolean resizeFullScreen)}
* @param activity
*/
public Keyboard(AppCompatActivity activity) {
this(activity, false);
}

public Keyboard(AppCompatActivity activity, boolean resizeOnFullScreen) {
this.activity = activity;
//calculate density-independent pixels (dp)
//http://developer.android.com/guide/practices/screens_support.html
Expand All @@ -49,13 +63,17 @@ public Keyboard(AppCompatActivity activity) {
final float density = dm.density;

//http://stackoverflow.com/a/4737265/1091751 detect if keyboard is showing
rootView = activity.getWindow().getDecorView().findViewById(android.R.id.content).getRootView();
FrameLayout content = activity.getWindow().getDecorView().findViewById(android.R.id.content);
rootView = content.getRootView();
list =
new ViewTreeObserver.OnGlobalLayoutListener() {
int previousHeightDiff = 0;

@Override
public void onGlobalLayout() {
if (resizeOnFullScreen) {
possiblyResizeChildOfContent();
}
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
rootView.getWindowVisibleDisplayFrame(r);
Expand Down Expand Up @@ -91,8 +109,33 @@ public void onGlobalLayout() {
}
previousHeightDiff = pixelHeightDiff;
}

private void possiblyResizeChildOfContent() {
int usableHeightNow = computeUsableHeight();
if (usableHeightPrevious != usableHeightNow) {
frameLayoutParams.height = usableHeightNow;
mChildOfContent.requestLayout();
usableHeightPrevious = usableHeightNow;
}
}

private int computeUsableHeight() {
Rect r = new Rect();
mChildOfContent.getWindowVisibleDisplayFrame(r);
return isOverlays() ? r.bottom : r.height();
}

private boolean isOverlays() {
final Window window = activity.getWindow();
return (
(window.getDecorView().getSystemUiVisibility() & View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN) ==
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
);
}
};
mChildOfContent = content.getChildAt(0);
rootView.getViewTreeObserver().addOnGlobalLayoutListener(list);
frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}

public void show() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public class KeyboardPlugin extends Plugin {
public void load() {
execute(
() -> {
implementation = new Keyboard(getActivity());
boolean resizeOnFullScreen = getConfig().getBoolean("resizeOnFullScreen", false);
implementation = new Keyboard(getActivity(), resizeOnFullScreen);
implementation.setKeyboardEventListener(this::onKeyboardEvent);
}
);
Expand Down
12 changes: 12 additions & 0 deletions keyboard/src/definitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,18 @@ declare module '@capacitor/cli' {
* @example "dark"
*/
style?: 'dark' | 'light';

/**
* There is an Android bug that prevents the keyboard from resizing the WebView
* when the app is in full screen (i.e. if StatusBar plugin is used to overlay the status bar).
* This setting, if set to true, add a workaround that resizes the WebView even when the app is in full screen.
*
* Only available for Android
*
* @since 1.1.0
* @example true
*/
resizeOnFullScreen?: boolean;
};
}
}
Expand Down

0 comments on commit 8e87836

Please sign in to comment.