React-native-navigation: Issue with scrolling when wrapping the screen's content inside a ScrollView. ANDROID ONLY

Created on 23 Nov 2017  ·  15Comments  ·  Source: wix/react-native-navigation

Issue Description

Hello,

When i wrap the screen's content inside a <ScrollView>, i cannot scroll down to bottom "0" (android only).

I noticed that this bug disappears only if i add fixed height to the parent View (i.e. height: 500), or hide both the tab bar and the navigation bar.

This happens in android device/emulator only.

As you can see in the screenshot below, the scrollbar cannot scroll to the bottom of the screen but you can see the content "overflowing". There is even more content behind the tab bar.

I tested it in a fresh project with just the react-native-navigation installed.

Any ideas?

Steps to Reproduce / Code Snippets / Screenshots

android


Environment

  • React Native Navigation version: 1.1.294
  • React Native version: 0.50.3
  • Platform: Android
  • Device info: Android Simulator
acceptediscussion 🏚 stale

Most helpful comment

I'm posting this quick fix for anyone having the same issue.

Make a wrapper component:

class Page extends Component {
    constructor(props) {
        super(props);
        this.state = {
            cachedHeight: '100%',
            containerHeight: null,
        }
    }

    render() {
        return(
            <View onLayout={(event) => {
                var {x, y, width, height} = event.nativeEvent.layout;
                if (this.state.cachedHeight !== height) {
                    this.setState({
                        cachedHeight: height
                    })
                }
                else {
                    this.setState({
                        containerHeight: height
                    })
                }
              }}
                style={{height: this.state.containerHeight || '100%'}}
            >
            <ScrollView>
                {this.props.children}
            </ScrollView>
        </View>
)}

Then wrap your screen's content inside it:

<Page>
    // content
</Page>

Not the best solution but works fine for me.

All 15 comments

Update!

I also noticed this:

this attribute onLayout={(event) => { var {x, y, width, height} = event.nativeEvent.layout; } gives us the position and dimensions of the component.

Now notice what happens in ios when i console.log the height value of the View wrapper component:

screen shot 2017-11-23 at 21 54 20

and what happens in android:
Notice that it triggers the onLayout infinetly, plus there are a lot of decimals there.

screen shot 2017-11-23 at 21 34 12

this is the value in android emulator but this time with a fixed value (height: 500).
Still many decimals, but triggers only once.

screen shot 2017-11-23 at 21 33 07

I made a temporary fix by using the state but the code is too dirty to keep it.

Maybe its the emulator's fault... I must run it on a real device and see what happens :/

Update:

Just ran this on a real android device, same thing happens!

Also encountered this, I'm running the same environment as @alekshs

Hiding navigator solves it for me for the moment however.

Same thing happens with me. Maybe is because of the new buildToolsVersion '26.0.2'

I'm posting this quick fix for anyone having the same issue.

Make a wrapper component:

class Page extends Component {
    constructor(props) {
        super(props);
        this.state = {
            cachedHeight: '100%',
            containerHeight: null,
        }
    }

    render() {
        return(
            <View onLayout={(event) => {
                var {x, y, width, height} = event.nativeEvent.layout;
                if (this.state.cachedHeight !== height) {
                    this.setState({
                        cachedHeight: height
                    })
                }
                else {
                    this.setState({
                        containerHeight: height
                    })
                }
              }}
                style={{height: this.state.containerHeight || '100%'}}
            >
            <ScrollView>
                {this.props.children}
            </ScrollView>
        </View>
)}

Then wrap your screen's content inside it:

<Page>
    // content
</Page>

Not the best solution but works fine for me.

I have the same issue since updating react-native and react-native-navigation. @alekshs wrapper solution works, but seems like a temporary solution.

I have the same issue, contentContainerStyle={{paddingBottom:xxx}} little bit helps, but in some cases it cause scroll flickering. I would say contentContainerStyle={{paddingBottom:xxx}} is a dirty workaround.

Confirming that I have the same issue but @alekshs solution works for me.

An example of the issue for those interested:
androidrekt

And after the fix:
androidworking

Note how scrollbar goes to the bottom and there's a big space between the bottom and the final item now. I didn't touch padding. Might be a placebo, but it also feels like it scrolls more smoothly.

There is temporary solution that works for me.
change navigator style to:

static navigatorStyle = {
  drawUnderNavBar: Platform.OS === 'android',
};

and add style to screen root component
marginTop: 56

@raphaelhovsepyan that fix also seems to work, so I'm changing to that for now, thank you!

Scroll bar seems to not reach the bottom still though, which the previous fix did achieve, but I've just hidden the scrollbar 🤷‍♂️

@alekshs You're awesome, your fix works.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
If you believe the issue is still relevant, please test on the latest version and report back. Thank you for your contributions.

The issue has been closed for inactivity.

Was this page helpful?
0 / 5 - 0 ratings