react-native scollview 刷新封装

本文介绍了一个React Native应用中实现下拉刷新和滚动到底部加载更多数据的完整示例。通过自定义组件和状态管理,展示了如何监听滚动事件以判断是否达到底部,并在底部显示加载状态。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

import React, { Component } from 'react';
import {
    AppRegistry,
    View,
    RefreshControl,
    ScrollView,
    TouchableWithoutFeedback,
    Text
} from 'react-native';
import LoadMoreFooter from './LoadMoreFooter';
class Row extends Component {
    _onClick = ()=>{
        console.log('onclick');
        this.props.onClick(this.props.data);
    };
    render(){
        return(
            <TouchableWithoutFeedback onPress={this._onClick}>
                <View style={{backgroundColor: '#3a5795', borderWidth: 1, padding: 20, borderColor: 'grey', margin: 5}}>
                    <Text style={{alignSelf:'center', color:'#fff'}}>
                        {this.props.data.text + '('+ this.props.data.clicks + ' clicks)'}
                    </Text>
                </View>
            </TouchableWithoutFeedback>
        )
    }
}
export default  class RNRefreshView extends Component {
    constructor(props){
        super(props);
        this.state = {
            isRefreshing: false,
            isshowAll:true,
            isLoadAll:false,
            loaded: 0,
            //使用map创建对象数组
            rowData: Array.from(new Array(20)).map((val, i)=>({
                text: 'Inital row' + i,
                clicks: 0
                })
            )
        }
    }
    //传递当前的对象,将clicks+1,刷新界面
    _onClick22 =(row)=> {
        console.log('1111' + row.text);
        row.clicks++;
        this.setState({
            rowData: this.state.rowData,
        });
    };

    //判断滚动到底部
    handleScrollEnd = (event) => {
        const contentHeight = event.nativeEvent.contentSize.height;
        const scrollViewHeight = event.nativeEvent.layoutMeasurement.height;
        const scrollOffset = event.nativeEvent.contentOffset.y;

        console.log(scrollOffset + scrollViewHeight,"444444444444",contentHeight);

        const isEndReached = scrollOffset + scrollViewHeight+45 >= contentHeight; // 是否滑动到底部
        const isContentFillPage = contentHeight >= scrollViewHeight; // 内容高度是否大于列表高度
    
        if (isContentFillPage && isEndReached) {
          this.loadMoreData();
        }
      };
      rows=()=>{
          if(this.state.rowData){
             
            return <View>
                    {this.state.rowData.map((row, i)=>{
                         return <Row key={i} data={row} onClick={this._onClick22}/>;
                    })}
                   
                    {this.state.isshowAll&&<LoadMoreFooter isLoadAll={this.state.isLoadAll}/>}
                </View>
          }
        
      }
    render(){
        //map遍历并创建Row类,row是数组的对象,i是索引位置
        
        const rows = this.state.rowData.map((row, i)=>{
            console.log('4444' + i);
            return <Row key={i} data={row} onClick={this._onClick22}/>;
        });
        return(
            <ScrollView style={{flex: 1, backgroundColor: '#ffaaff'}}
                        onScrollEndDrag={this.handleScrollEnd} //判断是否滚动到最底部
                        refreshControl={
                            <RefreshControl refreshing={this.state.isRefreshing}
                                            progressBackgroundColor={"#ff3377"}
                                            onRefresh={this._onRefresh}
                                            tintColor="#ff0000"
                                            title="Loading..."
                                            titleColor="#00ff00"
                                            colors={['#ff0000', '#00ff00', '#0000ff']}
                                            />
                        }>
                {this.rows()}
               
            </ScrollView>
        )
    }
    loadMoreData=()=>{
        if(this.state.loaded>30)return this.setState({isLoadAll:true});
          setTimeout(()=>{
            //.concat拼接字符串,数组
            let rowData = Array.from(new Array(10)).map((val, i)=>({
                text: 'Loaded row' + (+this.state.loaded + i),
                clicks: 0
            }))
                .concat(this.state.rowData);
            this.setState({
                loaded: this.state.loaded + 10,
                isRefreshing: false,
                rowData: rowData,
            })
        });
    }
    _onRefresh =()=>{
        this.setState({
            isRefreshing: true,
            loaded:10
        });
        //间隔5秒结束下拉刷新
        setTimeout(()=>{
            //.concat拼接字符串,数组
            let rowData = Array.from(new Array(10)).map((val, i)=>({
                text: 'Loaded row' + (+this.state.loaded + i),
                clicks: 0
            }));  
            this.setState({
                isRefreshing: false,
                rowData: rowData,
                isLoadAll:false
            })
        }, 2000);
    }
}

 

底部加载更多信息


/***
 * 
 * LoadMoreFooter 
 * listview加载跟多底部组件
 * @param{isLoadAll}判断是否加载完
 */
import React, { Component } from 'react';
  import {
      View,
      Text,
      StyleSheet,
  } from 'react-native';
  class LoadMoreFooter extends Component {
      constructor(props) {
          super(props);
      }
      render() {
          return (
              <View style={styles.footer}>
                <Text style={styles.footerTitle}>
                    {this.props.isLoadAll ? '已加载全部' : '正在加载更多……'}
                </Text>
              </View>
          )
      }
  }
  const styles = StyleSheet.create({
      footer: {
          flexDirection: 'row',
          justifyContent: 'center',
          alignItems: 'center',
          height: 40,
      },
      footerTitle: {
          marginLeft: 10,
          fontSize: 15,
          color: 'gray'
      }
  })
  
  export default LoadMoreFooter

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

随风小薇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值