React Native: вертикальное центрирование при использовании ScrollView
Я использую React Native, и у меня возникают проблемы с сохранением вертикального центрирования элементов, как только я представляю ScrollView. Чтобы продемонстрировать, я создал 3 приложения с React Native Playground. Все примеры имеют 2 страницы, и их можно переключать, нажимая голубую кнопку.
Пример 1:
В этом первом примере показаны вертикальные вертикальные блоки на странице 2. Это происходит потому, что к контейнеру применяются эти стили:
flex: 1,
flexDirection: 'column',
justifyContent: 'center',
https://rnplay.org/apps/lb5wSQ
Однако возникает проблема, как только вы переключаетесь на страницу 2, потому что все содержимое страницы не подходит, поэтому нам нужно ScrollView
.
Пример 2
В этом примере я обертываю все внутри ScrollView. Это позволяет прокручивать страницу 2, но теперь я потерял вертикальное центрирование страницы.
https://rnplay.org/apps/DCgOgA
Пример 3
Чтобы попытаться вернуть вертикальное центрирование страницы 1, я применяю flex: 1
к contentContainerStyle
ScrollView. Это фиксирует вертикальное центрирование на стр. 1, но я больше не могу прокручивать весь путь вниз до нижней части страницы на странице 2.
https://rnplay.org/apps/LSgbog
Как я могу исправить это, чтобы получить вертикальное центрирование элементов на стр. 1, но все же получить ScrollView для прокрутки до конца на странице 2?
Ответы
Ответ 1
Я решил эту проблему с помощью flexGrow вместо flex
<ScrollView contentContainerStyle={{flexGrow: 1}}>
Это приводит к тому, что контейнер содержимого растягивается, чтобы заполнить ScrollView, но не ограничивает максимальную высоту, поэтому вы все еще можете правильно прокручивать, когда контент расширяет границы ScrollView
Ответ 2
Вот мой подход:
Используйте внешний контейнер с flex : 1
, тогда в представлении прокрутки должно быть {flexGrow : 1, justifyContent : 'center'}
с использованием contentContainerStyle
, а не style
.
<View style={styles.mainContainer}>
<ScrollView
contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}}>
<View style={styles.scrollViewContainer}>
//Put your stuff here, and it will be centered vertical
</View>
</ScrollView>
</View>
Стили:
const styles = StyleSheet.create({scrollView : {
height : Dimensions.get('window').height, }, mainContainer : {
flex : 1 }, scrollViewContainer : { }, })
Ответ 3
EDIT: Теперь вы можете использовать <ScrollView contentContainerStyle={{flexGrow: 1}}>
.
Для старой версии React Native, не поддерживающей flexGrow
, используйте нижеприведенное решение.
Единственный способ, с помощью которого я уверен, сделать это как для iOS, так и для Android, - это установить minHeight
внутреннего вида на размер ScrollView
. Например:
<ScrollView
style={{flex: 1}}
contentContainerStyle={{minHeight: this.state.minHeight}}
onLayout={event => this.setState({minHeight: event.nativeEvent.layout.height})}
>
Примечание. Для простоты выстроены стили и функции выше, но вы, вероятно, захотите использовать постоянные ссылки для неизменных значений и запоминать изменяющийся стиль, чтобы предотвратить ненужные rerenders.
const {minHeight} = this.state;
// Manually memorise changing style or use something like reselect...
if (this.lastMinHeight != minHeight) {
this.lastMinHeight = minHeight;
this.contentContainerStyle = {minHeight: minHeight}
}
<ScrollView
style={styles.scrollViewStyle}
contentContainerStyle={this.contentContainerStyle}
onLayout={this.onScrollViewLayout}
>
Ответ 4
Там новое решение (к сожалению, iOS только на данный момент) - мы можем использовать centerContent
prop on Scrollview.
Ответ 5
Почему бы вам не обернуть только вторую страницу в ScrollView?
return (
<ScrollView >
<View style={styles.lipsum}>
{this.renderButton()}
<Text style={styles.lipsumText}>{lipsumText}</Text>
</View>
</ScrollView>
);
Просто измените свой первый пример, он работает как шарм :)
Ответ 6
Чтобы центрировать ScrollView по вертикали, вам нужна такая структура:
<View style={{flex: 1}}>
<View>
<ScrollView .../>
</View>
</View>
В противном случае, если вы хотите центрировать сам контент ScrollView, вам потребуется следующее:
<ScrollView contentContainerStyle={{flexGrow : 1, justifyContent : 'center'}} ...>