React一行中的原始组件数

时间:2016-05-13 09:32:53

标签: reactjs react-native flexbox

我把它当成一种运动。有28个组件。我希望最多有4行组件,每行最多有7个组件,最小值为1,具体取决于屏幕大小(28行)。你能帮我解决一下这个问题吗?我知道我可以使用flex-wrap:wrap样式,但我希望连续最多包含7个组件。作为React Native和Flexbox的新用户,请帮助我。

    <View style={styles.container}>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'red'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'green'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'yellow'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'brown'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'blue'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'red'}}></View>
      <View style={{ flex: 1, margin: 2, height: 40, backgroundColor: 'green'}}></View>
.
.
.
    </View>

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    justifyContent: 'center',
  },
});

3 个答案:

答案 0 :(得分:0)

这个问题无法以引导方式解决(列,行等)。 Flexbox缺乏根据屏幕大小使特定数量的组件连续出现的功能。

您需要使用ListView,以便ListView连续呈现7个组件。 ListView的renderRow函数遍历一个数组,并在一行中显示该数组的每个索引的内容。因此,在每个索引处,您需要定义包含7个属性的json,并以数组的形式返回所有这些属性,以使它们显示在一行中。

在我的项目中,我必须连续显示3个或更少的图像(如附加图像的媒体部分所示),所以我使用上面提到的方法来实现这一点。请在下面找到我的代码。这可能会对你有所帮助。

In Media section, at most 3 images can appear in a row

constructor() {
  // data saved in state
  this.state = {
    mediaFiles: [{image: "image link"}, 
                 {image: "image link"},
                 {image: "image link"},
                 {image: "image link"},
                 {image: "image link"},
                 {image: "image link"},
                 {image: "image link"},
                 {image: "image link"},
                ],
    dataSource: ds.cloneWithRows([])
  }
}

componentDidMount() {
  var temp = [];

  //to ensure three images appear in a row
  for (var index     = 0; index < this.state.mediaFiles.length; index = index + 3) {
      temp.push({
        image1: this.state.mediaFiles[index].image,
        image2: (index + 1) < this.state.mediaFiles.length ? this.state.mediaFiles[index + 1].image : null,
        image3: (index + 2) < this.state.mediaFiles.length ? this.state.mediaFiles[index + 2].image : null
      });
  }

  this.setState({
      dataSource: this.state.dataSource
       .cloneWithRows(temp)
  });
}

renderMediaThumbnails(rowData) {
  var mediaThumbnails = [],
    key = 0;

  for (var attribute in rowData) {
    if (rowData[attribute]) {
      mediaThumbnails.push(
        <View key={key++} style={Styles.imageWrapper}>
        <Image style={Styles.media} source={{uri: rowData[attribute]}} />
        </View>)
    }
  }
  return mediaThumbnails
}

renderRow(rowData) {
  return (
    <View style={Styles.mediaWrapper}>
      {this.renderMediaThumbnails(rowData)}
    </View>
  );
}

render() {
  return (
    <View style={Styles.statusAndMedia}>
      <ListView
        dataSource={this.state.dataSource}
        renderRow={this.renderRow.bind(this)} />
    </View>
  );
}

以下是样式:

mediaWrapper: {
  flex: 1,
  flexDirection: "row",
  justifyContent: "space-around",

  marginVertical: 3,
},

imageWrapper: {
  borderWidth: 2,
  borderColor: "#AE8B8C"
},

media: {
  height: 50,
  width: 85,

  resizeMode: "stretch"
}

答案 1 :(得分:0)

好的,我想我找到了解决方案。如果屏幕尺寸较大,我将父视图的宽度设置为屏幕的宽度或294(宽度为7个元素+边距)。也许硬编码到294就足够但我现在无法在小屏幕上查看它。

var width = Dimensions.get('window').width;

class Schedule extends React.Component {

  render() {
    return (
        <View style={styles.container}>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'red'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'green'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'yellow'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'brown'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'blue'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'red'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'green'}}></View>
          <View style={{ margin: 1, width: 40, height: 40, backgroundColor: 'red'}}></View>
        </View>
    )
  }
};


export default Schedule;

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    flexWrap: 'wrap',
    width: width > 294 ? 294 : width
  },
});

答案 2 :(得分:0)

现在不推荐使用ListView,可以改用SectionList或FlatList。