Skip to content
This repository has been archived by the owner on Feb 18, 2019. It is now read-only.

Commit

Permalink
Fix text input scroll when status bar is translucent
Browse files Browse the repository at this point in the history
Summary:Changed the implementation of `setTranslucent` because the old one used the view flag SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN which has the sad side effect of making the ScrollViews not adjust properly when the keyboard is opened. Instead I use `setOnApplyWindowInsetsListener` to hook in the insets calculation process and consume the top offset so the decor view doesn't add top padding for the status bar.

I also limited the translucent prop to API 21+ because `setOnApplyWindowInsetsListener` is not available before that and anyway the translucent prop is only useful with a semi-transparent status bar color which only works on API 21+.

**Test plan**
Reproduced the bug using this code in UIExplorer.
https://gist.github.com/janicduplessis/217b9994e35f960a1793

Tapping a text field that would be hidden by the soft keyboard should scroll the view so it is not hidden.

Also tested that setting the translucent prop on and off still works as before.

Fixes facebook#6455
Closes facebook#6481

Differential Revision: D3067199

Pulled By: mkonicek

fb-gh-sync-id: aa115f8688ac7e461e62c18ebb8ab77350d000f8
shipit-source-id: aa115f8688ac7e461e62c18ebb8ab77350d000f8
  • Loading branch information
janicduplessis authored and Facebook Github Bot 0 committed Mar 18, 2016
1 parent 18f38ec commit c76523f
Showing 1 changed file with 32 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.os.Build;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.view.WindowInsets;
import android.view.WindowManager;

import java.util.Map;
Expand Down Expand Up @@ -112,22 +113,39 @@ public void setTranslucent(final boolean translucent, final Promise res) {
res.reject(ERROR_NO_ACTIVITY, ERROR_NO_ACTIVITY_MESSAGE);
return;
}
UiThreadUtil.runOnUiThread(
new Runnable() {
@Override
public void run() {
int flags = activity.getWindow().getDecorView().getSystemUiVisibility();
if (translucent) {
flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
} else {
flags &= ~(View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
UiThreadUtil.runOnUiThread(
new Runnable() {
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
public void run() {
// If the status bar is translucent hook into the window insets calculations
// and consume all the top insets so no padding will be added under the status bar.
View decorView = activity.getWindow().getDecorView();
if (translucent) {
decorView.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() {
@Override
public WindowInsets onApplyWindowInsets(View v, WindowInsets insets) {
WindowInsets defaultInsets = v.onApplyWindowInsets(insets);
return defaultInsets.replaceSystemWindowInsets(
defaultInsets.getSystemWindowInsetLeft(),
0,
defaultInsets.getSystemWindowInsetRight(),
defaultInsets.getSystemWindowInsetBottom()
);
}
});
} else {
decorView.setOnApplyWindowInsetsListener(null);
}

ViewCompat.requestApplyInsets(decorView);
res.resolve(null);
}
activity.getWindow().getDecorView().setSystemUiVisibility(flags);
ViewCompat.requestApplyInsets(activity.getWindow().getDecorView());
res.resolve(null);
}
}
);
);
}
}

@ReactMethod
Expand Down

0 comments on commit c76523f

Please sign in to comment.