Вы подняли некоторые хорошие моменты и замечания - особенно в отношении использования flex-свойств родителя для размещения дочерних элементов с пробелом, вместо того, чтобы делегировать макет дочернему элементу родителя для переноса и добавления поля.
Я подготовил закуску, в которой описывается обе реализации: https://snack.expo.io/HyXElYL0V
Первый вариант: обернуть каждого ребенка и добавить поле: (GapLayout.js)
Здесь мы просто обертываем каждый дочерний объект объектом View и добавляем к нему любой отступ / отступ, за исключением последнего дочернего элемента, если это необходимо.
const GapLayout = ({ children }) => (
<View style={Styles.layoutContainer}>
{children.map((child, index) => {
const isLastChild = children.length === index + 1
return (
<View style={[Styles.layoutItemWrapper, { marginBottom: isLastChild ? 0 : 8 }]}>
{child}
</View>
)
})}
</View>
)
Это позволяет наценку, описанную вами выше:
<GapLayout>
<WideContent />
<WideContent />
<WideContent />
</GapLayout>
Второй вариант: установите соответствующую родительскую высоту так, чтобы justifyContent: 'space -ween' works (GapLayout2.js)
Было бы супер идеальным просто использовать {justifyContent: 'space -ween'} на родительском объекте, и это работает волшебно.Однако для создания пространства между элементами родитель должен быть выше, чем все дочерние элементы.
Поскольку мы добавляем несколько дочерних элементов неизвестной длины, нам нужно, чтобы родительский элемент имел высоту: неизвестная длина+ (количество детей - 1) * margin
class GapLayout2 extends React.Component {
constructor() {
super();
this.state = {
contentHeight: null,
};
}
setContentHeight = e => {
const { contentHeight } = this.state
const { children, itemMargin } = this.props
// Return if we already set a contentHeight to prevent an infinite-render-loop.
if(contentHeight) return
this.setState({
contentHeight: e.nativeEvent.layout.height + (children.length - 1) * itemMargin
})
}
render() {
const { children } = this.props;
const {contentHeight} = this.state
return (
<View onLayout={this.setContentHeight} style={[Styles.layoutContainer, contentHeight && { height: contentHeight }]}>
{children}
</View>
);
}
}
Что здесь происходит:
- Мы отображаем родительский элемент и все его содержимое.
- Мы используемобратный вызов onLayout для получения content-height.
- В setContentHeight мы затем устанавливаем setState с новым ContentHeight + margin.
Как только у нас будет contentHeight, мы затем визуализируем родительский объектс новой высотой:
style = {[Styles.layoutContainer, contentHeight && {height: contentHeight}]}
Это позволяет намта же наценка, без упаковки детей.И я полагаю, что это позволит прямым детям использовать flex: 1/2/10 друг с другом, поскольку все они имеют одного и того же родителя (тогда как если бы они были обернуты, это не сработало бы).
Будетлюблю видеть другие идеи и реализации.
Ура,