john doe
john doe

Reputation: 816

React native two column layout for dynamic elements not working

Multiple View elements with image inside need to be displayed in two column layout.

I am using following code (basically, getting dimension(x) of window and setting View width = x/2).

Parent container is flex: row.

But this does not seem to be working. I am getting only one image in a row instead of two like shown in image. What I am doing wrong?

const window = Dimensions.get('window');
const imageWidth = (window.width/3)+30;
const imageHeight = window.width/3;
export default class Brochures extends Component {
  render() {
    const brochuresView = brochuresData.map( Brochure );
    return (
      <ScrollView style={styles.container}>
        {brochuresView}
      </ScrollView>
    );
  }
}

const Brochure = ( data ) => {
  const {child, image} = styles;
  return (
    <View key={data.id} style={child}>
      <Image
        style={image}
        source={{uri: data.url}}
      />
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    flexWrap: 'wrap'
  },
  child: {
    width: window.width/2,
    alignItems: 'center',
    height: imageHeight+5,
    marginTop: 10
  },
  image: {
    width: imageWidth,
    height: imageHeight
  }
});

Wrong layout

Upvotes: 6

Views: 11212

Answers (2)

aimadnet
aimadnet

Reputation: 423

Try this:

const window = Dimensions.get('window');
const imageWidth = (window.width/3)+30;
const imageHeight = window.width/3;
export default class Brochures extends Component {
  render() {
    const brochuresView = brochuresData;
    var brochuresRow = [];
    var set = [];
    var setCounter = 0;

    for(var i = 0; i < brochuresView.length; i++) {
        set.push(brochuresView[i]);
        if((i + 1) % 2 == 0 || (i + 1) >= brochuresView.length) {
            setCounter++;
            brochuresRow.push(set);
            set = [];
        }
    }

    return (
      <ScrollView>
        {brochuresRow.map((row, i) => (
            <View key={i} style={styles.container}>
                {row.map((brochure, ii) => (
                    <View key={ii} style={styles.child}>
                        <Image
                            style={styles.image}
                            source={{uri: brochure.url}}
                        />
                    </View>
                ))}
            </View>
        ))}
      </ScrollView>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flexDirection: 'row',
    flex: 1,
    justifyContent: 'center'
  },
  child: {
    height: imageHeight+5,
    marginTop: 10
  },
  image: {
    width: imageWidth,
    height: imageHeight
  }
});

Upvotes: 0

Nader Dabit
Nader Dabit

Reputation: 53711

ScrollView takes a contentContainerStyle prop vs the normal style prop that will describe the styling.

From the docs:

These styles will be applied to the scroll view content container which wraps all of the child views. Example:

return ( <ScrollView contentContainerStyle={styles.contentContainer}> </ScrollView> ); ... const styles = StyleSheet.create({ contentContainer: { paddingVertical: 20 } });

So basically the only change you need with your code will be this:

<ScrollView contentContainerStyle={styles.container}>

vs this:

<ScrollView style={styles.container}>

Upvotes: 11

Related Questions