UNPKG

react-native-swrefresh-hm

Version:

react native pull refresh push loadMore scrollView,listView下拉刷新下拉加载控件,支持自定义,简单好用

288 lines (256 loc) 7.16 kB
/** * Created by sww on 2016/10/21. */ import React, { Component,PropTypes} from 'react'; import { StyleSheet, Text, View, ScrollView, ActivityIndicator, Animated, Easing, Dimensions, Image, AsyncStorage, ListView } from 'react-native'; import {SwRefreshScrollView,RefreshStatus,RefreshTitle} from './SwRefreshScrollView' /** *===============================================SwRefreshListView===================================== */ /** * 上拉加载更多的各状态 1 加载中 2 加载完毕 3 加载完毕 无更多数据 * @type {loading: number, finish: number, noMoreData: number}} */ export const LoadMoreStatus={ loading:1, finish:2, noMoreData:3 } export class SwRefreshListView extends ListView{ _isLoading = false // 构造 constructor(props) { super(props); // 初始状态 this.state = { loadStatus:LoadMoreStatus.finish }; } static propTypes={ //-----------------下拉刷新用于代码提示------------------------------------- /** * 刷新数据时的操作, 参数 end:function 操作结束时执行end() 以结束刷新状态 */ onRefresh:PropTypes.func, /** * 需要返回一个自定义的刷新视图, * 参数: * refresStatus:RefreshStatus, 0 下拉以刷新 1 松开以刷新 2 刷新中 * offsetY:number 下拉的距离 用于自定义刷新 */ customRefreshView:PropTypes.func, /** * 如果自定义刷新视图 需要传递这个视图的高度 默认视图情况下 此属性无效 */ customRefreshViewHeight:PropTypes.number, //----------------上拉加载----------------------------- /** * 自定义底部部刷新指示组件的渲染方法, * 参数 下拉状态 LoadMoreStatus */ customLoadMoreView:PropTypes.func, /** * 处于pushing(加载更多时)状态时执行的方法 * 参数:end,最后执行完操作后应该调用end(isNoMoreData)。 * isNoMoreData 表示当前是否已经加载完所有数据 已无更多数据 */ onLoadMore:PropTypes.func, /** * //默认样式中的上拉加载更多的提示语 */ pusuToLoadMoreTitle:PropTypes.string, /** * //默认样式中正在加载的提示语 */ loadingTitle:PropTypes.string, /** * //默认样式中已无更多时的提示语 */ noMoreDataTitle:PropTypes.string, /** * 是否显示底部的加载更多 通常用于全部数据不足一页 底部还显示加载更多导致的难看 */ isShowLoadMore:PropTypes.bool } /** * 重置已无更多数据的状态 通常用于下拉刷新数据完毕后 重置状态 */ resetStatus(){ this.setState({ loadStatus:LoadMoreStatus.finish }) } /** * 直接将状态置为没有更多数据状态 通常用于第一次刷新加载的后数据已全部加载 不必下拉刷新 * 也可使用 isShowLoadMore:PropTypes.bool将上拉加载组件隐藏 */ setNoMoreData(){ this.setState({ loadStatus:LoadMoreStatus.noMoreData }) } //-------------------1.0.7新增公开方法----------------------------------- /** * 手动调用刷新 */ beginRefresh(){ this.scrollView.beginRefresh() } /** * 手动结束刷新 不推荐 推荐end()回调 */ endRefresh(){ this.scrollView.endRefresh() } /* * 手动结束加载 * isNoMoreData 表示当前是否已经加载完所有数据 已无更多数据 * */ endLoadMore(isNoMoreData){ this._isLoading = false this.setState({ loadStatus:isNoMoreData ? LoadMoreStatus.noMoreData:LoadMoreStatus.finish }) } static defaultProps={ pusuToLoadMoreTitle:'上拉加载更多~~~~', loadingTitle:'加载中~~~', noMoreDataTitle:'已经加载到底啦( ̄︶ ̄)~~', isShowLoadMore:true } render(){ return( <ListView enableEmptySections={true} {...this.props} onEndReachedThreshold={1} onEndReached={(event)=>this._onEndReached(event)} renderFooter={ ()=>this._rendrFooter() } renderScrollComponent={(props) => <SwRefreshScrollView ref={(scrollView)=>{ if (scrollView){ this.scrollView = scrollView } }} {...props}/>} > </ListView> ) } //-----------------------上拉加载部分------------------------------- /** * 渲染footer和上拉加载组件 * @returns {XML} * @private */ _rendrFooter(){ if (!this.props.isShowLoadMore){ if (!this.props.renderFooter){ return ( <View style={{height:0.5}}> <View></View> </View> ) }else { return ( <View> {this.props.renderFooter()} </View> ) } } if (this.props.customLoadMoreView) { return ( <View> {this.props.renderFooter?this.props.renderFooter():null} {this.props.customLoadMoreView(this.state.loadStatus)} </View> ) } if (this.state.loadStatus == LoadMoreStatus.noMoreData){ return( <View> {this.props.renderFooter?this.props.renderFooter():null} <View style={footStyles.footer}> <Text style={footStyles.footerText}>{this.props.noMoreDataTitle}</Text> </View> </View> ) }else if(this.state.loadStatus == LoadMoreStatus.finish){ return( <View> {this.props.renderFooter?this.props.renderFooter():null} <View style={footStyles.footer}> {/*<ActivityIndicator/>*/} <Text style={footStyles.footerText}>{this.props.pusuToLoadMoreTitle}</Text> </View> </View> ) }else if(this.state.loadStatus == LoadMoreStatus.loading){ return( <View> {this.props.renderFooter?this.props.renderFooter():null} <View style={footStyles.footer}> <ActivityIndicator/> <Text style={footStyles.footerText}>{this.props.loadingTitle}</Text> </View> </View> ) } } /** * 上刷拉操作 * @param event * @private */ _onEndReached(event){ if (this.state.loadStatus == LoadMoreStatus.noMoreData || this._isLoading || !this.props.isShowLoadMore){ return } this._isLoading = true this.setState({ loadStatus:1 }) this.timer = setTimeout(()=>{ if (this.props.onLoadMore){ this.props.onLoadMore((isNoMoreData)=>{ this._isLoading = false this.setState({ loadStatus:isNoMoreData ? LoadMoreStatus.noMoreData:LoadMoreStatus.finish }) }) } },500) if(this.props.onEndReached){ this.props.onEndReached(event) } } componentDidUnMount() { this.timer && clearTimeout(this.timer); } } const footStyles = StyleSheet.create({ footer:{ height:30, flexDirection:'row', justifyContent:'center', alignItems:'center' }, footerText:{ fontSize:15, color:'#999999', marginLeft:10 } });