react native Expo完全基于ScrollView实现的下拉刷新和上拉触底加载
我直接封装成了一个组件
props参数为
static propTypes = { style:PropTypes.object, // 样式 refreshing:PropTypes.bool.isRequired,//是否开始下拉刷新动画 refreshBegin: PropTypes.func,// 开始下拉刷新回调 scrollEnd: PropTypes.func,// 触底回调 };
使用示例
import React from 'react'; import { View, } from 'react-native'; import styles from './style'; import HomeSwiper from "../../../components/HomeSwiper"; import HomeVideo from "../../../components/HomeVideo"; import ScrollViewPull from "../../../components/ScrollViewPull"; import {connect} from 'react-redux'; // 引入connect函数 import { getHomeSwiper, getHomeVideoCard, handleRefreshStatus } from '../../../actions/homeRecommendAction'; class HomeRecommend extends React.Component { constructor(props) { super(props); this.state = { refreshing: false, }; } componentDidMount(){ const {homeVideoCard} = this.props; this.props.getVideoCard(undefined,1,homeVideoCard); this.props.getSwiper(); } // 触底 handleScrollEnd = () => { const {currentPage,lastPage,homeVideoCard} = this.props; if(currentPage === lastPage){ this.props.getVideoCard(undefined,currentPage+1,homeVideoCard); } }; // 开始下拉刷新 handleRefreshBegin = () => { const {homeVideoCard} = this.props; this.props.getChangeRefresh(true); this.props.getSwiper(); this.props.getVideoCard(undefined,1,homeVideoCard); }; render() { const {navigation,swiperData,leftVideoData,rightVideoData,refreshing} = this.props; return ( <ScrollViewPull style={styles.scroll} refreshing={refreshing} scrollEnd={()=>this.handleScrollEnd()} // 触底回调 refreshBegin={()=>this.handleRefreshBegin()} // 开始下拉刷新回调 > <View style={styles.container}> <HomeSwiper navigation={navigation} swiperData={swiperData} /> <View style={styles.border}/> <HomeVideo navigation={navigation} leftVideoData={leftVideoData} rightVideoData={rightVideoData} /> </View> </ScrollViewPull> ); } } const mapStateToProps = (state) => ({ swiperData : state.homeRecommend.homeSwiperData, currentPage : state.homeRecommend.currentPage, homeVideoCard: state.homeRecommend.homeVideoCard, leftVideoData : state.homeRecommend.leftVideoData, rightVideoData : state.homeRecommend.rightVideoData, refreshing: state.homeRecommend.refreshing }); const mapDispatchToProps = (dispatch) => ({ getSwiper(){ dispatch(getHomeSwiper()); }, getChangeRefresh(refresh){ dispatch(handleRefreshStatus(refresh)); }, getVideoCard(id,page,homeVideoCard){ dispatch(getHomeVideoCard(id,page,homeVideoCard)); }, }); export default connect(mapStateToProps,mapDispatchToProps)(HomeRecommend);
组件全部代码为:
import React from 'react'; import { ScrollView, RefreshControl, } from 'react-native'; import PropTypes from 'prop-types'; class ScrollViewPull extends React.Component { static navigationOptions = { header: null, }; static propTypes = { style:PropTypes.object, // 样式 refreshing:PropTypes.bool.isRequired,//是否开始下拉刷新动画 refreshBegin: PropTypes.func,// 开始下拉刷新回调 scrollEnd: PropTypes.func,// 触底回调 }; constructor(props) { super(props); this.initState(); } initState=()=>{ }; onRefresh = () => { this.props.refreshBegin(); }; // 监听上拉触底 _contentViewScroll = (e: Object) => { let offsetY = e.nativeEvent.contentOffset.y; //滑动距离 let contentSizeHeight = e.nativeEvent.contentSize.height; //scrollView contentSize高度 let oriageScrollHeight = e.nativeEvent.layoutMeasurement.height; //scrollView高度 if (offsetY + oriageScrollHeight >= contentSizeHeight){ this.props.scrollEnd(); } }; render() { const {children,refreshing,style} = this.props; return ( <ScrollView style={[{flex:1},style]} showsVerticalScrollIndicator={false} scrollToIndex refreshControl={ <RefreshControl refreshing={refreshing} onRefresh={this.onRefresh} /> } onMomentumScrollEnd = {this._contentViewScroll} > {children} </ScrollView> ); } } export default ScrollViewPull;