React-native 滚动到顶部并拉动刷新 iOS

gal*_*lgo 4 react-native react-native-ios

我有一个 react-native 应用程序,当 FlatList 在 iOS 中刷新时,我想滚动到顶部。我可以使用以下方法滚动到 FlaList 的顶部:

this.componentRef.FlatList.scrollToOffset({x: 0, y: 0, animated: true});
Run Code Online (Sandbox Code Playgroud)

现在,该列表启用了下拉刷新,因此我想在 iOS 中的刷新指示器上方滚动。

我试过:

this.componentRef.FlatList.scrollToOffset({x: 0, y: -20, animated: true});
Run Code Online (Sandbox Code Playgroud)

并使用 ref 将 RefreshControl 声明为 refreshcontrol(使用回调 ref 声明):

this.componentRef.FlatList.refreshcontrol.scrollToOffset({x: 0, y: 0, animated: true});
Run Code Online (Sandbox Code Playgroud)

this.componentRef.refreshcontrol.scrollToOffset({x: 0, y: 0, animated: true});
Run Code Online (Sandbox Code Playgroud)

但没有工作。有没有人知道我可以在刷新指示器上方滚动的方法(如果它打开)?这仅在 iOS 中发生,因为 Android 的刷新指示器的工作方式不同。

更新:

由于 RefrehControl 组件无法使用 scrollToOffset,因此它不会工作。这让我回到如何在 FlatList 中的 RefreshControl 上方滚动。我的最后一次尝试:

this.FlatList.scrollToOffset({x: 0, y: 0, animated: true});
Run Code Online (Sandbox Code Playgroud)

仍然滚动到列表的开头,但“RefreshControl”在视觉上是隐藏的。

我也尝试在上面添加一个空的 ScrollView 并滚动到它,因为它是空的,它不起作用。有任何想法吗?

更新 2

澄清一下,这就是一切的称呼(简化):

Main.js 中的 _scrollAndRefresh 方法:

  _scrollAndRefresh = () => {
     this.setState({
       loading: true
     }, () => {
       this.CustomFlatList._scrollToTop();
     });
  }
Run Code Online (Sandbox Code Playgroud)

在 Main.js 中渲染组件:

  <CustomFlatList ref={(ref) => {
      this.CustomFlatList = ref}}
    onRefresh={this._handleRefresh} loading={this.state.loading}/>
Run Code Online (Sandbox Code Playgroud)

Main.js 中的 _handleRefresh 方法:

  _handleRefresh = () => {
    this.setState({
      loading: true
    }, () => {
      // REFRESH ACTION
    })
  };
Run Code Online (Sandbox Code Playgroud)

_scrollToTop 方法 CustomFlatList.js:

  _scrollToTop = () => {
    if (Platform.OS === 'ios' && this.props.loading) {
      this.FlatList.scrollToOffset({x: 0, y: 0, animated: true});
    }
    else {
      this.FlatList.scrollToOffset({x: 0, y: 0, animated: true});
    }
  }
Run Code Online (Sandbox Code Playgroud)

和 FlatList CustomFlatList.js:

<FlatList
  ref={(ref) => { this.FlatList = ref; }}
  refreshControl={<RefreshControl
            refreshing={this.props.loading}
            onRefresh={this.props.onRefresh}
        />}
/>
Run Code Online (Sandbox Code Playgroud)

Val*_*Val 5

由于<RefreshControl />从手势检测刷新行为,<FlatList />滚动方法对其没有影响;而你只是试图破解它。

建议这样做。您仍然滚动到顶部并显示刷新,更直接:

constructor(props) {
  super(props);
  this.state = {
    refreshing: false,
  }
}

/// scroll to top, and show refresh at the same time
scrollToTopAndRefresh() {
  this.componentRef.FlatList.scrollToOffset({x: 0, y: 0, animated: true});
  this.setState({
    refreshing: true,
  }, () => {
    this.refresh();
  });
}

refresh() {
  /// put your refresh logic here
}

componentRef = {};
render() {
  return (
    <FlatList ref={ (ref) => this.componentRef.FlatList = ref }
      refreshControl={
        <RefreshControl
          refreshing={this.state.refreshing}
          onRefresh={() => this.refresh()}
        />
      }
    />
  );
}
Run Code Online (Sandbox Code Playgroud)

更新 2:

我根据您的需要制作了一个简单可行的代码。

import React, { Component } from 'react';
import {
    Image,
    View,
    FlatList,
    Text,
    StyleSheet,
    Button,
    RefreshControl,
} from 'react-native';

export class App extends Component {
    constructor(props) {
        super(props);
        this.scrollToTopAndRefresh = this.scrollToTopAndRefresh.bind(this);
        this.doRefresh = this.doRefresh.bind(this);
        this.state = {
            refreshing: false,
        }
    }

    scrollToTopAndRefresh() {
        this.flatlistref.scrollToOffset({y: 0, animated: true});
        this.setState({refreshing: true}, this.doRefresh);
    }

    doRefresh() {
        /// do refresh work here /////
        //////////////////////////////
        setTimeout( () => this.setState({refreshing: false}), 1000);
    }

    flatlistref = null;
    render() {
        return (
            <View style={{flex: 1}}>
                <FlatList
                    ref={(ref) => this.flatlistref = ref}
                    data={Array(30).fill(1)}
                    renderItem={() => <Text style={styles.line}>This is one line.</Text>}
                    refreshControl={
                        <RefreshControl
                            refreshing={this.state.refreshing}
                            onRefresh={this.doRefresh}
                        />
                    }
                />
                <Button title='Scroll To Top' onPress={this.scrollToTopAndRefresh} />
            </View>
        )
    }
}

const styles = StyleSheet.create({
    line: {
        height: 50,
        paddingTop: 17,
        textAlign: 'center',
        backgroundColor: 'orange',
        borderWidth: 1,
        borderColor: 'purple',
    }
});
Run Code Online (Sandbox Code Playgroud)

结果:

在此处输入图片说明