React Native flexbox - 如何做百分比 || 列 || 响应式 || 网格等

IT技术 javascript css reactjs flexbox react-native
2021-03-25 19:46:54

在过去几周在 iOS 上使用 react native 之后,我似乎遇到了 flex 样式的一些缺点……尤其是在涉及“响应”行为时。

例如,假设您要创建一个包含卡片的视图(这些卡片的元数据来自 API)。您希望卡片为视图宽度的 50% 减去边距和填充,并在每 2 个之后换行。

在此处输入图片说明

我对此视图的当前实现将返回的数组拆分为包含 2 个项目的行。列表容器有flex: 1, flexDirection: 'column,行有flex: 1,然后每张卡片都有flex: 1最终结果是每行有 2 列,它们均匀地占据视图宽度的一半。

似乎在 React Native 样式中没有简单的方法可以做到这一点,而不使用 javascript 对数据进行某种预处理,以便正确显示样式。有没有人有什么建议?

4个回答

使用 flexbox 可能有更好的方法来实现这一点,但我通常定义“百分比”助手vw以及vh视口宽度和视口高度,以 CSS 视口大小测量单位命名:

import {Dimensions} from 'react-native';

function vw(percentageWidth) {
  return Dimensions.get('window').width * (percentageWidth / 100);
}

function vh(percentageHeight) {
  return Dimensions.get('window').height * (percentageHeight / 100);
}

要在网格中流动项目,您可以计算项目的适当大小,考虑边距和视口大小:

const COLUMNS = 3;
const MARGIN = vw(1);
const SPACING = (COLUMNS + 1) / COLUMNS * MARGIN;

const grid = {
  flex: 1,
  flexWrap: 'wrap',
  flexDirection: 'row',
  justifyContent: 'flex-start'
};

const cell = {
  marginLeft: MARGIN,
  marginTop: MARGIN,
  width: vw(100) / COLUMNS - SPACING
}

return (
  <View style={grid}>
    {this.props.things.map(thing => <View style={cell} />)}
  </View>
)

如果您的项目数量已知且数量有限,您应该只使用此技术 - 对于任意数量的卡片,您应该ListView出于性能原因使用,并手动将数据集拆分为行。

这种方法的问题在于,如果您允许更改方向,它将不起作用。
2021-05-25 19:46:54
这似乎是迄今为止最好的解决方案。感谢您分享@jevakallio。
2021-06-13 19:46:54
@Joon 正确 - 我刚刚发布了一个库,它可以更轻松地在横向和纵向方向上设置React Native 组件的样式:github.com/FormidableLabs/react-native-responsive-styles
2021-06-21 19:46:54

React Native 已经有百分比支持

<View style={[style.parent]}>
    <View style={[style.child, {backgroundColor: '#996666'} ]} />
    <View style={[style.child, {backgroundColor: '#339966'} ]} />
    <View style={[style.child, {backgroundColor: '#996633'} ]} />
    <View style={[style.child, {backgroundColor: '#669933'} ]} />
</View>

var style = StyleSheet.create({
    parent: {
        width: '100%', 
        flexDirection: 'row', 
        flexWrap: 'wrap'
    },
    child: {
        width: '48%', 
        margin: '1%', 
        aspectRatio: 1,
    }
})

在此处输入图片说明

身高问题。高度不能降低
2021-05-27 19:46:54

您可以使用 justifyContent: 'space-between'

<View style={styles.feed}>
    <View style={styles.card} />
    <View style={styles.card} />
    <View style={styles.card} />
    <View style={styles.card} />
 </View>

feed: {
 flex: 1,
 flexDirection: 'row',
 flexWrap: 'wrap',
 padding: 16,
 justifyContent: 'space-between'  }


card: {
 backgroundColor: 'white',
 width: '48%',
 aspectRatio: 1,
 marginBottom: 16   }

截屏

这可能会解决这个问题

<View style={{
              flex: 1,
              flexDirection: 'row',
              flexWrap: 'wrap',
            }}>
              {array?.map((item, itemIndex) => {
                return (
                  <View style={{
                    flexBasis: '50%',
                    height:OPTIONAL,
                    width:OPTIONAL
                  }}>
                   // YOUR CONTENT HERE
                  </View>
                )
              })}
            </View>