React-Native 使用 Flatlist 滚动到顶部

Posted

技术标签:

【中文标题】React-Native 使用 Flatlist 滚动到顶部【英文标题】:React-Native scroll to top with Flatlist 【发布时间】:2018-10-30 09:20:46 【问题描述】:

我在滚动到我的平面列表顶部时遇到了很多麻烦,因此我们将不胜感激任何帮助!

本质上,它从 firebase 获取前 5 个项目,然后当调用 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>
);

【问题讨论】:

【参考方案1】:

正确的语法是

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

你也可以使用

scrollToIndex

【讨论】:

抱歉这么久了,但我想将此标记为正确答案。它以前不起作用,因此可能是旧 RN 版本之一中的错误,但现在我在 v0.57 上它运行良好。 如何用动画平面列表做到这一点?我既没有看到scrollToOffset 也没有看到scrollToIndex this.flatListRef?.current?.scrollToOffset( animated: true, offset: 0 ); 为我工作【参考方案2】:

以防万一有人不知道如何用钩子做到这一点,这里有一个例子

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

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

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

主要区别在于你通过.current访问它

【讨论】:

【参考方案3】:

对于反应钩子

    import React, useRef from 'react' 声明它-> const flatListRef = useRef() 设置为ref=flatListRef 称它为flatListRef.current.scrollToOffset(animated: false, offset: 0)

【讨论】:

【参考方案4】:

在这个答案中,我提到了一个非常简单的代码 sn-p,其中有 2 个按钮可以向右或向左滚动平面列表。您可以使用此代码来实现以编程方式滚动平面列表的其他用例。

//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>
     );

【讨论】:

以上是关于React-Native 使用 Flatlist 滚动到顶部的主要内容,如果未能解决你的问题,请参考以下文章

React-Native:使用 pagingEnabled 时获取 FlatList 中的当前页面

react-native ScrollView 嵌套 FlatList滚动

使用 react-native 的 FlatList 时获取未定义不是对象

React-Native 使用 Flatlist 滚动到顶部

React-native flatlist 在 isLoading 上的组件之间共享道具

React-Native:在ios中传递空数组时,Flatlist和Sectionlist引发异常