Search code examples
react-nativescrollviewhorizontalscrollview

ScrollView React Native Horizontal Not Working


I am developing app with RN 0.59.8. I am trying to create scrollable view horizontally with ScrollView. Here is basis of my code (sorry I couldn't share more detail):

import React, { Component, Fragment } from 'react';
import {
  ScrollView,
} from 'react-native';
import {
  Container,
  Content,
} from 'native-base';
import { Grid, Row } from 'react-native-easy-grid';

import ChildComponent from './ChildComponent';

class MyComponent extends Component {
  render() {
    const {
      data,
    } = this.props;

    return (
      <Container>
        <Content>
          <Grid>
            <Row>
              <ScrollView
                horizontal
                contentContainerStyle={{
                  flex: 1, flexGrow: 1, flexDirection: 'row',
                }}
              >
                {
                  data.map((item, index) => {
                    const order = index;

                    return (
                      <Fragment key={order}>
                        {
                          <ChildComponent />
                        }
                      </Fragment>
                    );
                  })
                }
              </ScrollView>
            </Row>
          </Grid>
        </Content>
      </Container>
    );
  }
}

export default MyComponent;

Current behavior:

  1. if contentContainerStyle={{ flex: 1, flexGrow: 1, flexDirection: 'row' }}, the second data not appear
  2. if contentContainerStyle={{ flex: 1, flexGrow: 1, flexDirection: 'column' }}, the second data appear vertically
  3. if contentContainerStyle={{ flexDirection: 'row' }}, the second data not appear and the content is wider than the screen width

My objection is:

  1. I want to make it scrollable horizontally
  2. Each data will fit the screen width

Any help would be very helpful. Thank you!!!


Solution

  • Straight from React Native docs, for the scroll view's children to be arranged horizontally in a row instead of vertically in a column the only prop you need to use it's horizontal.

    <ScrollView horizontal>
      <Child/>
    </ScrollView>
    

    I created a snack to show you, @abranhe/stackoverflow-56721203:

    to make it fit the screen width, play with your component and:

    import { Dimensions } from 'react-native';
    
    Dimensions.get('width').width
    

    The demo source code:

    import React, { Component } from 'react';
    import { Text, View, StyleSheet, Image, ScrollView } from 'react-native';
    import data from './data';
    
    export default class App extends Component {
      renderCity(city) {
        return (
          <View style={styles.cardContainer}>
            <View style={styles.card}>
              <Image source={{ uri: city.img }} style={styles.image} />
              <Text style={styles.title}>{city.title}</Text>
            </View>
          </View>
        );
      }
    
      render() {
        return (
          <View style={styles.container}>
            <ScrollView horizontal>
              {data.map(city => {
                return this.renderCity(city);
              })}
            </ScrollView>
          </View>
        );
      }
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        backgroundColor: '#ecf0f1',
        marginTop: 30,
      },
      title: {
        margin: 24,
        fontSize: 18,
        fontWeight: 'bold',
        textAlign: 'center',
      },
      image: {
        width: 200,
        height: 200,
        borderRadius: 10,
        marginTop: 10,
      },
      cardContainer: {
        justifyContent: 'center',
      },
      card: {
        backgroundColor: 'white',
        justifyContent: 'center',
        alignItems: 'center',
        margin: 20,
        borderRadius: 10,
        width: 220,
      },
    });
    

    Keep in mind

    Some UI components from native-base have absolute values, you may change your theme variables, to make them fit your needs.

    If you don't want to show your scroll indicator, you can set to false the ScrollView's showsHorizontalScrollIndicator prop.