Я уже некоторое время делаю макеты для экранов в React Native с помощью Flexbox и не сталкивался с какими-либо проблемами до сегодняшнего дня, когда мне пришлось сделать этот очень простой макет:
Я хочу, чтобы раздел содержимого был в 3 раза больше, чем верхний и нижний колонтитулы, поэтому, естественно, я установил для гибкости значение 1 (заголовок), 3 (содержимое), 1 (нижний колонтитул).
Несмотря ни на что, контент остается таким, как если бы он был flex: 1.
Единственный способ, которым я мог управлять макетом так, как я хотел, - это оставить flex: 1 содержимого и установить для нижнего и верхнего колонтитула значение flex: 0.33.
Я подозреваю, что это может иметь какое-то отношение к опоре ScrollView contentContainerStyle, которую я установил на flexGrow: 1, flexShrink: 1.
Вот минимальный пример, который воспроизводит это.
С минимальной доработкой у меня работает, я использовал такой стиль:
const styles = StyleSheet.create({
screen: {
backgroundColor: 'lightgray',
flex: 1,
},
header: {
flex: 0.33,
backgroundColor: 'lightblue',
justifyContent: 'center',
alignItems: 'center',
},
scrollView: {
flex: 1,
},
footer: {
backgroundColor: 'lightpink',
flex: 0.33,
alignItems: 'center',
justifyContent: 'center',
},
});
Полный код >>> https://snack.expo.io/Hk9tbHR4Q
Вот результат:
@Franch Теперь я понимаю ваш вопрос ... Это потому, что ScrollView не может самостоятельно определять свой размер (это особенность ScrollView, всегда имеет flex: 1). Он должен дождаться, пока другие компоненты выберут свой захват (1, 3, 0,33 ...), а затем scrollView сделает все остальное!
Обновление 2:
Мне указали, что Я не должен использовать ListView, завернутый в ScrollView, поскольку может произойти следующее:
Это может привести к странному поведению, например, к непрерывному срабатыванию onEndReached.
Обертывание ListView внутри ScrollView заставляет родительское действие прокрутки доминировать над дочерним действием прокрутки, что приводит к прокрутке только ScrollView.
Хорошо, я не уверен, почему это работает, но нашел решение после нескольких часов попыток:
После шага, упомянутого в Обновление 1, я добавил следующий стиль flexGrow: 0 к FlatList внутри ScrollView, и содержимое стало центрированным, и уменьшение размера содержимого до тех пор, пока оно не станет прокручиваемым, также отлично работает.
В основном это результирующий код:
render() {
return (
<View style = {{ flex: 1 }}>
<View style = {{ flex: 1 }}>
<Text>HEADER</Text>
</View>
<View style = {{ flex: 6 }}> // Change this to affect ScrollView size
<ScrollView contentContainerStyle = {{ flexGrow: 1, justifyContent: 'center' }}>
<FlatList
data = {listItems}
renderItem = {Item}
keyExtractor = {(index, item) => item}
style = {{ flexGrow: 0 }} // This was the solution to centering
/>
</ScrollView>
</View>
<View style = {{ flex: 1 }}>
<Text>FOOTER</Text>
</View>
</View>
);
}
Вот последний Рабочее решение, если вы хотите его попробовать.
Обновление 1:
Удалось контролировать размер ScrollView с помощью Flex в обычном режиме (то есть с использованием целочисленных значений гибкости, как предполагалось в первую очередь) с помощью упаковка ScrollView внутри представления с flex: 1.
Обратной стороной является то, что если я установил для раздела «Прокручиваемый» (контент) достаточно высокое значение гибкости, чтобы его больше нельзя было прокручивать, контент не отображается по центру. Даже если применяется justifyContent: 'center'.
Вот ОБНОВЛЕНИЕ 1 пример.
Обратите внимание, что я уже заявлял, что изменение гибкости верхнего и нижнего колонтитула на десятичные дроби работает, но я хотел предотвратить это, потому что это очень утомительно. Было бы хорошо узнать, почему он так себя ведет с ScrollView.