Динамически настраивайте высоту прокрутки во время выполнения

#react-native #react-native-scrollview

Вопрос:

Я разрабатываю собственный проект react.

У меня есть ScrollView в MyComponent , содержание ScrollView состоит из :

  • a MySubComponent ,
  • a Text
  • компонент Image

Все содержимое/данные вышеуказанных компонентов имеют динамическую длину или высоту. Итак, я хотел бы настроить высоту содержимого моего ScrollView «на лету» во время выполнения.

Для достижения этой цели я планирую отключить automaticallyAdjustContentInsets ScrollView , как вы можете видеть из приведенного ниже фрагмента кода. Затем создайте переменную состояния, в которой будет храниться последнее значение contentInsetBottom . Но я не уверен, как я могу рассчитать высоту дочерних компонентов, чтобы я мог позвонить setContentInsetBottom(totalHeight) , чтобы обновить высоту содержимого моего ScrollView .

(Я почти уверен, что мой план сработает, если я буду знать, как рассчитать высоту каждого моего дочернего компонента ScrollView .)

Кто-нибудь может меня немного подвести?

 const MyComponent = ({myText, image}) => {

   // I have a state of the contentInsetBottom for the ScrollView
   const [contentInsetBottom, setContentInsetBottom] = useState(0);

   // how can I get the height of each children component, sum them up amp; call setContentInsetBottom(totalHeight) here ?

   return (
   <ScrollView
        automaticallyAdjustContentInsets={false}
        contentInset={{top: 0, bottom: contentInsetBottom}}
        style={styles.scrollView}
        contentContainerStyle={styles.contentContainer}>

        <MySubComponent />
        <Text>{myText}</Text>
        <Image source={{uri: image?.uri}}>
   </ScrollView>)
}
 

Ответ №1:

Оберните все содержимое внутри <ScrollView> в a <View> . Затем используйте onLayout, чтобы получить высоту этого родительского представления.

   const handleScrollContentLayout = (e) => {
    const { height } = e.nativeEvent.layout
    setScrollLayoutHeight(height)
  }

...

<View onLayout={handleScrollContentLayout}>
{ /* scrollView content... */ }
</View>
 

Затем вы можете использовать scrollLayoutHeight в соответствии с вашими потребностями, чтобы установить высоту во время выполнения.

Комментарии:

1. Спасибо. Это работает, однако высота содержимого выглядит вдвое больше, чем фактическое содержимое в целом. Я должен setScrollLayoutHeight(height*0.5) это сделать, чтобы избежать большого пустого пространства в нижней части содержимого ScrollView.

2. приставка. запишите значение высоты и проверьте, не меняется ли оно. Обычно onLayout вызывается несколько раз, и конечное значение часто оказывается правильным. В моем случае я получал 0 при первом рендеринге. Поэтому я установил возвращенную высоту в состояние с помощью крючка useState для соответствующего обновления.

3. reactnative.dev/docs/прямая манипуляция#measurecallback -> Проверьте также этот обратный вызов. Это еще один вариант динамического определения высоты. Хотя раньше я им не пользовался.