【问题标题】:React-Native scroll to top with FlatlistReact-Native 使用 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>
);

【问题讨论】:

    标签: react-native react-native-flatlist react-ref


    【解决方案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】:

      对于反应钩子

      1. import React, {useRef} from 'react'
      2. 声明它-> const flatListRef = useRef()
      3. 设置为ref={flatListRef}
      4. 称它为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>
             );
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-03-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-19
          • 2020-07-07
          • 2019-08-13
          • 1970-01-01
          相关资源
          最近更新 更多