React-native: [FlatList] Horizontal FlatList can't scroll to rest of content when RTL is true for localization

Created on 23 Mar 2017  路  12Comments  路  Source: facebook/react-native

Description

Localizing for a Right-to-Left language, Farsi, causes ListViews to reverse in a way that the scrollview can't scroll to the rest of the content. Here is a GIF of its behaviour -

rtl-scrollview

Reproduction

An ordinary horizontal Listview will suffice. See mine below.

<ListView
          dataSource={this.dataSource}
          renderRow={this._renderRow.bind(this)}
          contentContainerStyle={styles.scrollViewStyle}
          horizontal={true}
          showsHorizontalScrollIndicator={false}
          automaticallyAdjustContentInsets={true}
          removeClippedSubviews={true}
          enableEmptySections={true}
  />

const styles = {
scrollViewStyle: {
        justifyContent: 'flex-end',
        flexDirection: 'row',
        alignItems: 'center',
    }
}

https://gist.github.com/annelorraineuy/7998b0275ba2b255366a288bb87aca7a

Solution

Provide support for how to fix Listview when in RTL for localization.

Additional Information

  • React Native version: 0.39.2
  • Platform: Android (did not test on iOS)
  • Development Operating System: MacOS
  • Dev tools: Webstorm IDE and Chrome debugging.

Probably noteworthy to also say I've tried using https://github.com/exponent/react-native-invertible-scroll-view but I still can't scroll to the rest of the content. It only looks reversed but the behaviour is the same.

Will appreciate any leads or advice : (

Locked

Most helpful comment

I came up with this approach on small datasets, any issues with it?

I18nManager.allowRTL(true);
I18nManager.forceRTL(true);

const FlatListProps = (data = []) => {
    const props = {
        style: {},
        data: data
    };

    if (I18nManager.isRTL && Platform.OS === 'android') {
        props.style.flexDirection = 'row-reverse';
        props.data = props.data.reverse()
        props.inverted = true
    }

    return props
}
<FlatList
     horizontal={true}
     keyExtractor={(item, index) => index}
     renderItem={this.renderItem}
     {...FlatListProps(this.props.data)} />

All 12 comments

Temporary workaround just for the scrollview to the get to the rest of the content.

See renderScrollComponent on ListView.

Layout will look LTR though, not RTL as it should be.

<ListView
                dataSource={this.dataSource}
                renderRow={this._renderRow}
                contentContainerStyle={[
                    listViewStyle, this.props.style
                ]}
                renderScrollComponent={(props) =>
                    <ScrollView
                        {...props}
                        style={{
                            flexDirection: I18nManager.isRTL ? 'row-reverse' : 'row' }}
                    />
                }
                horizontal={true}
                showsHorizontalScrollIndicator={false}
                automaticallyAdjustContentInsets={true}
                removeClippedSubviews={true}
                enableEmptySections={false}
            />

0.39.2 doesn't have scrollToEnd() so I don't know what else to do.

Can you try out FlatList or any of the new list views? ListView is being deprecated in favor of them. Please do open a new issue if you find the new list views have a similar issue.

@hramos Now I've converted to FlatList. Yes, this issue still persists in RN 0.44.0.

Alright, let's reopen this - can you edit your original post and make it about FlatList?

Here is the updated FlatList code, still with the same issue:

<FlatList
                refs={comp => this._listView = comp}
                keyExtractor={(item, index) => item.uniqueId}
                data={this.props.data}
                renderItem={this._renderRow}
                contentContainerStyle={[
                    listViewStyle, this.props.style
                ]}
                getItemLayout={(data, index) => ({
                    length: ICON_WIDTH,
                    offset: ICON_WIDTH * index,
                    index
                })}
                // scrollRenderAheadDistance={300}
                // initialNumToRender={10}
                horizontal={true}
                showsHorizontalScrollIndicator={false}
                automaticallyAdjustContentInsets={false}
                removeClippedSubviews={false}
                enableEmptySections={false}
            />

Just upgraded to RN 0.44.2 and my app also crashes when its on this screen. Not very sure if its related to FlatList itself, because I have a lot of items on my FlatList. On 0.44.0 it did not crash though...

Hi there! This issue is being closed because it has been inactive for a while. Maybe the issue has been fixed in a recent release, or perhaps it is not affecting a lot of people. Either way, we're automatically closing issues after a period of inactivity. Please do not take it personally!

If you think this issue should definitely remain open, please let us know. The following information is helpful when it comes to determining if the issue should be re-opened:

  • Does the issue still reproduce on the latest release candidate? Post a comment with the version you tested.
  • If so, is there any information missing from the bug report? Post a comment with all the information required by the issue template.
  • Is there a pull request that addresses this issue? Post a comment with the PR number so we can follow up.

If you would like to work on a patch to fix the issue, contributions are very welcome! Read through the contribution guide, and feel free to hop into #react-native if you need help planning your contribution.

I came up with this approach on small datasets, any issues with it?

I18nManager.allowRTL(true);
I18nManager.forceRTL(true);

const FlatListProps = (data = []) => {
    const props = {
        style: {},
        data: data
    };

    if (I18nManager.isRTL && Platform.OS === 'android') {
        props.style.flexDirection = 'row-reverse';
        props.data = props.data.reverse()
        props.inverted = true
    }

    return props
}
<FlatList
     horizontal={true}
     keyExtractor={(item, index) => index}
     renderItem={this.renderItem}
     {...FlatListProps(this.props.data)} />

Thanks a lot @skmail for this solution! Of course this is hacky, but at least it works without too much tinkering.

for large data(over 30 items) ListView nor FlatList do not function with RTL

@annelorraineuy
hi,
did you find a solution?

no news on this?

legacyImplementation={true} will do the trick,
but not all Flatlist features will be supported see

Was this page helpful?
0 / 5 - 0 ratings