React-Native прокрутите вверх с помощью Flatlist

У меня много проблем с прокруткой до верхней части моего Flatlist, поэтому любая помощь будет принята с благодарностью!

По сути, он выбирает первые 5 элементов из firebase, затем, когда вызывается onEndReached, мы добавляем следующие 5 элементов в список:

data: [...this.state.data, ...results]

На данный момент у меня есть кнопка обновления в верхней части моего просмотра, которая выполняет следующие действия:

this.flatListRef.scrollToOffset({ animated: true, y: 0 });

Если я щелкну по нему, когда будут отображены первые 5 элементов, он прокручивается в верхнюю часть списка, как и ожидалось. Проблема возникает только после того, как список был добавлен (я полагаю, что элементы не видны?).

Я также пробовал "ScrollToItem", однако, полагаю, это не работает из-за следующего из документов React Native:

Примечание. Невозможно прокрутить до мест за пределами окна рендеринга, не указав реквизит getItemLayout.

Может кто-нибудь объяснить, что происходит, или знать, что я делаю не так?

Заранее спасибо!

getItemLayout: (не совсем уверен, что это делает или как определить длину, смещение и т. д.)

getItemLayout = (data, index) => (
{ length: 50, offset: 50 * index, index }
)

return (
  <View>
    <FlatList
      ref={(ref) => { this.flatListRef = ref; }}
      onScroll={this.handleScroll}
      data={this.state.data}
      keyExtractor={item => item.key}
      ListFooterComponent={this.renderFooter()}
      onRefresh={this.handleRefresh}
      refreshing={this.state.newRefresh}
      onEndReached={this.handleEndRefresh}
      onEndReachedThreshold={0.05}
      getItemLayout={this.getItemLayout}
      renderItem={this.renderItem}
    />
    {this.state.refreshAvailable ? this.renderRefreshButton() : null}
  </View>
);

5 ответов

Правильный синтаксис

this.flatListRef.scrollToOffset({ animated: true, offset: 0 });

и вы также можете использовать

scrollToIndex

На всякий случай, если кто-то не понимает, как это сделать с помощью хуков, вот пример

function MyComponent() {
    const flatListRef = React.useRef()

    const toTop = () => {
        // use current
        flatListRef.current.scrollToOffset({ animated: true, offset: 0 })
    }

    return (    
        <FlatList
            ref={flatListRef}
            data={...}
            ...
        />
    )
}

Основное отличие состоит в том, что вы получаете к нему доступ через .current

Если кому интересно, как использовать хуки для React:

  1. import React, {useRef} from 'react'
  2. объявить -> const flatListRef = useRef()
  3. установить это как ref={flatListRef}
  4. назови это как flatListRef.current.scrollToOffset({animated: false, offset: yourOffset})

Метод ниже решил мою проблему. Проверьте это:

      const flatList = useRef();
const moveToTop = () => flatList.current.scrollToIndex({ index: 0 });

return (
  <View>
    <FlatList
      ref={flatList}
      onScroll={this.handleScroll}
      data={this.state.data}
      keyExtractor={item => item.key}
      ListFooterComponent={this.renderFooter()}
      onRefresh={this.handleRefresh}
      refreshing={this.state.newRefresh}
      onEndReached={this.handleEndRefresh}
      onEndReachedThreshold={0.05}
      getItemLayout={this.getItemLayout}
      renderItem={this.renderItem}
    />
    {this.state.refreshAvailable ? this.renderRefreshButton() : null}
  </View>
);

Как добавить прокрутку вверх в FlatList в приложении ReactNative

В этом ответе я упомянул очень простой фрагмент кода, в котором есть две кнопки для прокрутки списка вправо или влево. Вы можете использовать этот код для достижения других вариантов использования программной прокрутки плоского списка.

      //import
import React, { useEffect, useState, useRef, useCallback } from 'react';

//React class declaration.
const DocumentsInfo = ({ route, navigation }) => {
  
  //state variable
  const [documentsArray, setDocumentsArray] = useState({}); // array being shown in flatlist.
  const [maxVisibleIndex, setMaxVisibleIndex] = useState(0); // highest visible index currently visible.
  const [minVisibleIndex, setMinVisibleIndex] = useState(0); // lowest visible index currently visible.
  const flatListRef = useRef() // reference of flatlist.

  // callback for whenever flatlist scrolls
  const _onViewableItemsChanged = useCallback(({ viewableItems, changed }) => {
     setMaxVisibleIndex(viewableItems[viewableItems.length - 1].index);
     setMinVisibleIndex(viewableItems[0].index);
  }, []);

  // function for scrolling to top
  const scrollToTop = () => { 
    setMinVisibleIndex(0);
    setMaxVisibleIndex(0);
    flatListRef.current.scrollToIndex({ index: 0, animated: true });
  };

  // function for scrolling to bottom
  const scrollToBottom = () => { 
    let temp = documentsArray.length - 1;
    setMinVisibleIndex(temp);
    setMaxVisibleIndex(temp);
    flatListRef.current.scrollToIndex({ index: temp, animated: true });
  };

  // function for moving flatlist left and right by 1 index
  const moveNextPreviousHorizontalFlatlist = (isNext) => {
     if (isNext) {
        let maxVisible = maxVisibleIndex + 1;
        if (maxVisible < documentsArray.length) {
           let minVisible = minVisibleIndex + 1;
           setMinVisibleIndex(minVisible);
           setMaxVisibleIndex(maxVisible);
           flatListRef.current.scrollToIndex({ index: maxVisible, animated: true });
        }
     }
     else {
        let minVisible = minVisibleIndex - 1;
        if (minVisible >= 0) {
           let maxVisible = maxVisibleIndex - 1;
           setMinVisibleIndex(minVisible);
           setMaxVisibleIndex(maxVisible);
           flatListRef.current.scrollToIndex({ index: minVisible, animated: true });
        }
      }
   };

   // UI 
   return (
       <View>
       { maxVisibleIndex != documentsArray.length - 1 &&
          <View style={styles.Refresh}>
            <TouchableOpacity onPress={() =>
               moveNextPreviousHorizontalFlatlist(true)
            }>
             <Image style={styles.Refresh} source={Refresh} />
            </TouchableOpacity>
           </View>
       }

       <FlatList
         ref={flatListRef}
         onViewableItemsChanged={_onViewableItemsChanged}
         showsHorizontalScrollIndicator={false}
         horizontal
         keyExtractor={(item, index) => item.fileName + index}
         data={documentsArray}
         renderItem={({ item, index }) => {
           return (  <DocumentListItem /> )
         }}
       />

       { minVisibleIndex != 0 &&
         <View style={styles.Refresh}>
           <TouchableOpacity onPress={() =>
              moveNextPreviousHorizontalFlatlist(false)
            }>
             <Image style={styles.Refresh} source={Refresh} />
           </TouchableOpacity>
         </View>
       }
     </View>
     );
Другие вопросы по тегам