Подтвердить что ты не робот

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?

4b9b3361

Ответ 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'}} ...>