ptomasroos / react-native-tab-navigator

A tab bar that switches between scenes, written in JS for cross-platform support
MIT License
2.4k stars 416 forks source link

Android - Tab bar is sometimes pushed up by the keyboard #48

Closed Traviskn closed 6 years ago

Traviskn commented 8 years ago

This issue is not happening consistently, but sometimes when using a text input on android the keyboard pushes the tab bar up to the middle of the screen. I'm not sure if this is a bug with this component or with the react native styles in android.

Has anyone else experienced this kind of issue?

chrisbianca commented 8 years ago

I've just noticed this happening for me too. It seems to be happening randomly and a I haven't been able to figure out a pattern as yet.

It's almost as if sometimes when the keyboard opens it goes above the content on the page, and other times it pushes the whole content upwards?

I'm not massively familiar with Android development so I don't know whether it's possible to control how the keyboard opens either in react native or outside of react native?

chrisbianca commented 8 years ago

A look on the Android documentation highlighted this: http://developer.android.com/guide/topics/manifest/activity-element.html#wsoft

No default behaviour is specified in the react native standard AndroidManifest.xml so it will adopt "adjustUnspecified" as a default. This means it is up to the system to decide whether the window should resize or pan on display of the keyboard, hence the seemingly inconsistent nature of this issue.

Setting the property to "adjustResize" means that it will always resize the screen, which I think is the best behaviour, though this means the tab bar always shows.

A simple way to fix would be to detect the keyboard showing and hide the tab bar when it displays. This would only be required on Android though. Thoughts?

chrisbianca commented 8 years ago

An alternative approach is to set the property to "adjustNothing" which isn't in the documentation but means that when the keyboard displays the screen isn't modified in anyway.

This prevents the tab bar from ever showing, but also means that any scroll areas displayed in the underlying window are the full screen height, which may or may not be what you're looking for.

ide commented 8 years ago

@chrisbianca thanks for the investigation. Your analysis is right -- it depends on how you've configured the keyboard to behave.

I think ideally Android would match iOS's behavior -- adjustNothing gets close to that but has issues when firing keyboard events IIRC -- so the keyboard would not resize the window and would simply cover it. You want this for two reasons: consistency between platforms (and keyboard handling is really tricky -- who wants to have to think through it twice?), and Android's design guidelines recommend tab bars at the bottom now so "native" Android is going to encounter the same problem.

But if you configure your app differently to resize the window when the keyboard pops up, the suggested solution of manually detecting that via the keyboard events and hiding/showing the tab bar sound right. That's something you should do in your own application code.

chrisbianca commented 8 years ago

@ide thanks for confirming. Having tried the three different options for Android, I agree that adjustNothing would be the closest to iOS's behaviour.

Unfortunately, you're right in your assessment that keyboard events in Android don't match iOS: you have KeyboardDidHide and KeyboardDidShow instead of KeyboardWillHide and KeyboardWillShow. This means something like the module https://github.com/APSL/react-native-keyboard-aware-scroll-view is more difficult to implement for Android.

Mad-hu commented 7 years ago

config Android project ->AndroidManifest.xml ->add this node==> android:windowSoftInputMode=" stateAlwaysHidden | adjustPan " qq 20161221160844

Amurmurmur commented 7 years ago

@Mad-hu That escalated quickly, it just worked like a charm, thank you so much 👍

Pianist038801 commented 7 years ago

@Mad-hu Nice job! Thanks. 👍

hami9x commented 6 years ago

@Mad-hu's solution uses "adjustPan", which would cause everything to shift up whenever the keyboard appears, which is not desirable. Is there a solution that fixes this when using "adjustResize"?

ptomasroos commented 6 years ago

Will close since this issue is more than a year, feel free to a open a new if this is still a issue.

mdomygit commented 5 years ago

@Mad-hu Thank you very much. Worked for me.

yash786agg commented 5 years ago
Here is the solution for this fix
- android:windowSoftInputMode="adjustResize" in Manifest File
- Make a class "CommentKeyBoardFix.Java" and copy and paste the below code.

public class CommentKeyBoardFix
{
private View mChildOfContent;
private int usableHeightPrevious;
private FrameLayout.LayoutParams frameLayoutParams;
private Rect contentAreaOfWindowBounds = new Rect();

public CommentKeyBoardFix(Activity activity)
{
    FrameLayout content = activity.findViewById(android.R.id.content);
    mChildOfContent = content.getChildAt(0);
    mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(this::possiblyResizeChildOfContent);
    frameLayoutParams = (FrameLayout.LayoutParams) mChildOfContent.getLayoutParams();
}

private void possiblyResizeChildOfContent()
{
    int usableHeightNow = computeUsableHeight();
    if (usableHeightNow != usableHeightPrevious)
    {
        int heightDifference = 0;
        if (heightDifference > (usableHeightNow /4))
        {
            // keyboard probably just became visible
            frameLayoutParams.height = usableHeightNow - heightDifference;
        }
        else
        {
            // keyboard probably just became hidden
            frameLayoutParams.height = usableHeightNow;
        }
        mChildOfContent.layout(contentAreaOfWindowBounds.left, contentAreaOfWindowBounds.top, contentAreaOfWindowBounds.right, contentAreaOfWindowBounds.bottom);
        mChildOfContent.requestLayout();
        usableHeightPrevious = usableHeightNow;
    }
}

private int computeUsableHeight()
{
    mChildOfContent.getWindowVisibleDisplayFrame(contentAreaOfWindowBounds);
    return contentAreaOfWindowBounds.height();
}
}

And then call this class in your Activity or Fragment
setContentView(R.layout.your_comments_layout)
CommentKeyBoardFix(this) ---> For Kotlin
or
new CommentKeyBoardFix(this) ---> For Java
AGPatel commented 5 years ago

@Mad-hu I changed but still shift up the tab view

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.ak1">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme">
      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="stateAlwaysHidden|adjustPan">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

inkedscreenshot_1551245918_li

smitthakkar1 commented 5 years ago

@AGPatel try to rebuild the app