美文网首页Web 前端开发 让前端飞
react-native 编写的一个点击展开,下拉刷新案例

react-native 编写的一个点击展开,下拉刷新案例

作者: Miss_Fairy | 来源:发表于2017-08-17 15:47 被阅读0次

下面这个主要是一个微信分享的页面,包含两个tab,主要做的是第二个就爱不正经的tab页面,主要包含功能,朋友圈配图默认展示两张图片,下面又展开按钮,可以展开可以收起。朋友圈配图类似一个两列的瀑布流,包含下拉刷新功能,上拉加载功能。下面代码有些是引用公司的一些组件库,可能直接复制代码跑不通,接口跑不通,可以自己制造假数据,不过基本的逻辑还是可以参考的。

image.png image.png image.png
/**
 * Created by lyy45532 on 17/8/9.
 */
'use strict';
import React, { Component } from 'react';
import {
    View,
    Text,
    StyleSheet,
    TouchableOpacity,
    Image,
    ScrollView,
    Platform,
    RefreshControl,
    AsyncStorage,
    NativeModules
} from 'react-native';
import {
  TOKEN_NAME,
  Updateareaphone,
  GetCircleCoverAPI,
  GetIllustrationAPI
} from '../../Common/services/Interfaces';
import {XGFetch} from '../../Common/services/XGFetch';
import PlatformIndexView from './MyTextView';
import HeadNavBar from '../../Common/components/HeadNavBar';
import { IconData } from '../../Common/style/IconBase';
import { WinStyle } from '../../Common/style/ComStyle';
//toast提示组件
import {ToastShow} from '../../Common/components/ToastShow';
import Loading from '../../Common/components/Spinner';
//分享弹窗组件
import ShareComponent from '../../Common/components/ShareComponent';
import {wakeUpWechat} from '../../Common/services/rnModuleFn';
const rnModule = Platform.OS == 'android' ?  NativeModules.ToastModule : NativeModules.RNModule;
const winWidth = WinStyle.WinWidth,
      winHeight = WinStyle.WinHeight,
      imgScale = winWidth / 750;
const PicW = (winWidth - 30)/2;
const btnList = [
        {
            name:'严选好素材',
            tabId:1
        },
        {
            name:'就爱不正经',
            tabId:2
        }
      ];
export default class NewShare extends Component{
    constructor(props) {
      super(props);
      //就爱不正经
      this.leftHeight = 0;
      this.rightHeight = 0;
      this.leftArr = [];
      this.rightArr = [];
      this.totalSize = 1;
      this.state = {
        tabId:1,
        IsAllData:false,
        isLoad:true,
        isLoad1:true,
        isRefreshingBad: false,
        IsClickImg:false,
        IsMore:false,
        errorStatus:false,
        errorStatus1:false,
        CoverImgList:[],
        myImgList:[],
        currentSize:1,
      };
      let {navigate,goBack} = this.props.navigation;
    }
    componentDidMount(){
      // 获取用户信息
      AsyncStorage.getItem(TOKEN_NAME).then( (storeData) => {
          storeData = JSON.parse(storeData);
          this.storeData = storeData;
          setTimeout(() => {
            this.getMyPicList();
            this.getMyCoverList();
          },500)
      });
    }
    //返回上一页
    backToMain(){
      this.props.navigation.goBack();
    }
    tanBtn(tabId){
        this.setState({
            tabId:tabId
        })
    }
    //获取朋友圈封面图
    getMyCoverList(){
      let url = GetCircleCoverAPI.get({
            Token:this.storeData.Token,
        });
      console.log(url);
        XGFetch(url,(json)=>{
            let result = null;
            try {
                result = JSON.parse(json.result);
            } catch (e) {
                result = {};
                this.setState({
                  errorStatus1:true,
                  isLoad1:false
                })
            }
            // 出现错误
            if (json.gwerror > 0) {
                this.setState({
                  errorStatus1:true,
                  isLoad1:false
                })
                return;
            }
            if(result.ResCode != 1000){
                this.setState({
                  errorStatus1:true,
                  isLoad1:false
                })
                return;
            }
            this.setState({
              CoverImgList:result.PicList,
              isLoad1: false,
              errorStatus1:false
            })

        },(err)=>{
            this.setState({
              errorStatus1:true,
              isLoad1:false
            })
        })
    }
    //获取朋友圈配图图片列表
    getMyPicList(){
      let url = GetIllustrationAPI.get({
            Token:this.storeData.Token,
            PageIndex:this.state.currentSize,
            Pagesize:10
        });
      console.log(url);
        XGFetch(url,(json)=>{
            let result = null;
            try {
                result = JSON.parse(json.result);
            } catch (e) {
                result = {};
                this.setState({
                  errorStatus:true,
                  isLoad:false
                })
            }
            // 出现错误
            if (json.gwerror > 0) {
                this.setState({
                  errorStatus:true,
                  isLoad:false
                })
                return;
            }
            if(result.ResCode != 1000){
                this.setState({
                  errorStatus:true,
                  isLoad:false
                })
                return;
            }
            this.totalSize = Math.ceil(result.TotalCount/10);
            result.PicList.map((item,i) => {
                const picH = PicW * item.ImgHeight / item.ImgWidth;
                item.ImgWidth = PicW;
                item.ImgHeight = picH;
                if(this.leftHeight <= this.rightHeight){
                    this.leftArr.push(item);
                    this.leftHeight += picH + 10;
                } else {
                    this.rightArr.push(item);
                    this.rightHeight += picH + 10;
                }
            });
            this.setState({
              myImgList:result.PicList,
              isLoad: false,
              isRefreshingBad:false,
              errorStatus: false
            })
        },(err)=>{
            this.setState({
              errorStatus:true,
              isLoad:false
            })
        })
    }
    //滚到底部事件
    scrollFn(e){
      let { contentOffset,contentSize,layoutMeasurement } = e.nativeEvent;
      let [ offsetY,visibleH,contentH ]  = [ contentOffset.y,layoutMeasurement.height,contentSize.height ];
      //距离底部40距离的时候开始加载第二页
      if (contentH - offsetY <= visibleH + 40 && this.lastContentHeight != contentH && this.state.currentSize < this.totalSize) {
        this.lastContentHeight = contentH;
        this.setState({
          currentSize:this.state.currentSize + 1,
          isRefreshingBad:false,
        },() => {
          //重新获取数据
          this.getMyPicList();
        })
      }
      if(this.state.currentSize >= this.totalSize && !this.state.IsAllData){
        this.setState({
          IsAllData: true
        })
      }
    }
    //下拉刷新事件
    onRefreshBad(){
      this.setState({
        isRefreshingBad:true,
        IsMore:false,
        IsAllData:false,
        currentSize:1,
      },()=>{
          this.leftArr = [];
          this.rightArr = [];
          this.leftHeight = 0;
          this.rightHeight = 0;
          this.lastContentHeight = null;
          this.getMyPicList();
          this.getMyCoverList();
      });
    }
    //点击加载更多朋友圈图片
    getCoverImg(){
      this.setState({
        IsMore: !this.state.IsMore
      })
    }
    //点击图片看弹窗详情
    showBigImgForShare(ImgUrl){
      this.setState({
        showBigImgUrl:ImgUrl,
        IsClickImg:true
      })
    }
    //网络错误,点击重试
    badRetry(){
      this.setState({
        isLoad: true,
        errorStatus:false,
        isLoad1: true,
        errorStatus1:false
      },() => {
        this.getMyPicList();
        this.getMyCoverList();
      })
    }
    //点击保存图片
    collectImg(ImgUrl){
      rnModule.saveImage([ImgUrl],(event)=>{
            if(!event){
              ToastShow('保存失败,请重新保存');
              talkingData('xg_fail_wechat_save_picture','',{'employee':this.storeData.JobNumber,'error': '图片保存失败'});
            }else{
              ToastShow('图片已保存到本地相册');
            }
        })
    }
    //点击分享
    shareImg(ImgUrl){
      alert(ImgUrl)
    }
    //渲染列表
    returnScrollContent(){
        if (this.state.isLoad || this.state.isLoad1) {
          return(<View style={styles.loadingStyleBad}>
                    <Loading />
                  </View>)
        }
        if (this.state.errorStatus || this.state.errorStatus1) {
          return(<TouchableOpacity activeOpacity={0.8} style={styles.loadingStyleBad} onPress={this.badRetry.bind(this)}>
                    <Text>网络错误,请点击重试</Text>
                 </TouchableOpacity>)
        }
        return (<View style={{flex:1}}>
                  {
                    this.state.CoverImgList && this.state.CoverImgList.length > 0 ?
                    (<View style={{flex:1}}>
                        <View style={styles.coverImgBoxBad}>
                            <Image source={require('../../images/wechatshare/titleImg.png')} style={styles.ImgTitelBad}/>
                            <Text style={styles.titleTextStyleBad}>朋友圈封面图</Text>
                        </View>
                        <View style={{flexDirection:'row',flexWrap:'wrap'}}>

                            {
                                this.state.CoverImgList.map((item,i) => {
                                   return(
                                    (i>=2 && !this.state.IsMore) ? null :
                                    <TouchableOpacity activeOpacity={0.8} key={'picback'+i} style={[styles.clickImgBad,{marginLeft:i%2===0 ? 0 : 10,marginTop:i>1 ? 10 : 0}]} onPress={this.showBigImgForShare.bind(this,item)}>
                                        <Image source={{uri:item}}
                                               style={[styles.clickImgBad,{borderRadius:4}]} />
                                    </TouchableOpacity>
                                   )
                                })
                            }
                        </View>
                        {
                          this.state.CoverImgList.length > 2 ?
                          (
                            <TouchableOpacity activeOpacity={0.8} style={styles.downRowBtnBad} onPress={this.getCoverImg.bind(this)}>
                                <Image source={require('../../images/wechatshare/downRow.png')} style={[styles.rowBad,{transform:!this.state.IsMore ? [{rotate:'0deg'}] :[{rotate:'180deg'}]}]}/>
                            </TouchableOpacity>
                            ):null
                        }
                      </View>) : null
                  }
                  {
                    this.state.myImgList && this.state.myImgList.length > 0 ?
                    (<View style={{flex:1}}>
                        <View style={styles.showPicTitelBoxBad}>
                            <Image source={require('../../images/wechatshare/titleImg.png')} style={styles.ImgTitelBad}/>
                            <Text style={styles.titleTextStyleBad}>朋友圈配图</Text>
                        </View>
                        <View style={styles.boxModelBad}>
                          <View style={{width:PicW,marginRight:5}}>
                              {
                                  this.leftArr.map((item,i) => {
                                      return(
                                          <TouchableOpacity key={'leftImg' + i} style={{marginTop: i > 0 ? 10 : 0}} activeOpacity={0.8} onPress={this.showBigImgForShare.bind(this,item.ImgUrl)}>
                                              <Image source={{uri:item.ImgUrl}} style={{width:item.ImgWidth,height:item.ImgHeight,borderRadius:4}}/>
                                          </TouchableOpacity>
                                          )
                                  })
                              }
                          </View>
                          <View style={{width:PicW,marginLeft:5}}>
                              {
                                  this.rightArr.map((item,i) => {
                                      return(
                                          <TouchableOpacity key={'rightImg' + i} style={{marginTop: i > 0 ? 10 : 0}} activeOpacity={0.8} onPress={this.showBigImgForShare.bind(this,item.ImgUrl)}>
                                              <Image source={{uri:item.ImgUrl}} style={{width:item.ImgWidth,height:item.ImgHeight,borderRadius:4}}/>
                                          </TouchableOpacity>
                                          )
                                  })
                              }
                          </View>

                          {
                            this.state.IsAllData ?
                            (<View style={styles.allDataBad}>
                                <Text>====到底啦,没有更多数据了====</Text>
                            </View>):null
                          }

                        </View>
                      </View>) : null
                  }
                </View>)
    }
    //当点击图片的时候渲染弹窗
    renderDialog(){
       return(
          this.state.IsClickImg ?
          (<View style={styles.dialogBoxBad}>
              <View style={styles.dialogBgBad}>
              </View>
              <View style={styles.dialogContentBad}>
                  <View style={styles.dailogTopBoxBad}>
                      <View style={styles.dialogImgBoxBad}>
                         <Image resizeMode={'contain'} source={{uri:this.state.showBigImgUrl}} style={styles.dailogImgStyleBad}/>
                      </View>
                      <View style={styles.dailogTextBoxBad}>
                        <TouchableOpacity activeOpacity={0.8} style={styles.collectBoxBad} onPress={this.collectImg.bind(this,this.state.showBigImgUrl)}>
                          <Text style={{fontSize:16,color:'#333'}}>保存图片</Text>
                        </TouchableOpacity>
                        <TouchableOpacity activeOpacity={0.8} style={[styles.collectBoxBad,styles.shareBoxBad]} onPress={this.shareImg.bind(this,this.state.showBigImgUrl)}>
                          <Text style={{fontSize:16,color:'#f0f0f0'}}>分享</Text>
                        </TouchableOpacity>
                      </View>
                  </View>
                  <TouchableOpacity style={styles.closeDialogBoxBad} onPress={()=>{this.setState({IsClickImg:false})}}>
                      <View style={styles.closeBtnLeftBad}></View>
                      <View  style={styles.closeBtnRightBad}></View>
                  </TouchableOpacity>
              </View>

            </View>):null
        )
    }
    render(){
        return(
                <View style={styles.wrapper}>
                  {this.renderDialog()}
                  <HeadNavBar
                      title='素材'
                      noiOSHeadColor
                      leftIcon={IconData.newBackIcon}
                      leftIconPress={this.backToMain.bind(this)}
                  />
                  <View style={{height:44,flexDirection:'row'}}>
                    {
                      btnList.map((item,i) => {
                          return (
                                <TouchableOpacity style={styles.tabBtn} activeOpacity={1} key={i} onPress={this.tanBtn.bind(this,item.tabId)}>
                                    <View style={[styles.tabTextBox,{borderBottomColor:this.state.tabId === item.tabId ? '#3ac569' : '#f6f6f6'}]}>
                                        <Text style={{fontSize:14,color:this.state.tabId === item.tabId ?  '#3ac569' :'#333'}}>{item.name}</Text>
                                    </View>
                                </TouchableOpacity>
                              )
                      })
                    }
                  </View>
                  {
                    this.state.tabId === 1 ?
                    (<View style={{flex:1,justifyContent:'center',alignItems:'center'}}><Text>严选好素材页面</Text></View>):
                    (<ScrollView
                        onScroll={this.scrollFn.bind(this)}
                        refreshControl={
                                      <RefreshControl
                                        refreshing={this.state.isRefreshingBad}
                                        onRefresh={this.onRefreshBad.bind(this)}
                                        colors={['#3ac569']}
                                        tintColor={'#3ac569'}
                                        progressBackgroundColor='#fff' />
                                      }
                        scrollEventThrottle={200}
                        style={{flex:1,marginLeft:10,marginRight:10}}>
                        {
                          this.returnScrollContent()
                        }
                     </ScrollView>)
                  }
                </View>
            )
    }
}
const styles = StyleSheet.create({
      wrapper: {
        backgroundColor: '#fff',
        flex: 1,
        position:'relative',
      },
      tabBtn: {
        flex:1,
        backgroundColor:'#f6f6f6',
        paddingLeft:30,
        paddingRight:30
      },
      tabTextBox: {
        borderBottomWidth:2,
        flex:1,
        justifyContent:'center',
        alignItems:'center',
      },
      downRowBtnBad: {
        width: winWidth - 20,
        height:12,
        paddingTop:20,
        paddingBottom:12,
        justifyContent:'center',
        alignItems:'center'
      },
      boxModelBad: {
        flex:1,
        flexDirection:'row',
        flexWrap:'wrap'
      },
      loadingStyleBad: {
        height: Platform.OS == 'ios' ? winHeight - 108 : winHeight - 88,
        alignItems:'center',
        justifyContent:'center'
      },
      titleTextStyleBad: {
        position:'absolute',
        fontSize:16,
        color:'#333'
      },
      dialogBoxBad: {
        flex:1,
        position:'absolute',
        left:0,
        top:0,
        bottom:0,
        right:0,
        zIndex:1,
        justifyContent:'center',
        alignItems:'center'
      },
      dialogBgBad: {
        width:winWidth,
        height:winHeight,
        backgroundColor:'#333',
        opacity:0.7,
        position:'absolute',
        top:0,left:0
      },
      dialogImgBoxBad: {
        height:700 * imgScale,
        paddingTop:20,
        width:winWidth-40,
        borderTopLeftRadius:4,
        borderTopRightRadius:4,
        overflow:'hidden'
      },
      collectBoxBad: {
        width:(winWidth-80)/2,
        height:40,
        borderWidth:1,
        borderColor:'#ccc',
        borderRadius:4,
        marginLeft:15,
        justifyContent:'center',
        alignItems:'center'
      },
      closeDialogBoxBad: {
        width:44,
        height:44,
        borderWidth:1,
        borderRadius:22,
        borderColor:'#fff',
        position:'absolute',
        bottom:0,
        justifyContent:'center',
        alignItems:'center',
      },
      coverImgBoxBad: {
        height:50,
        justifyContent:'center',
        alignItems:'center'
      },
      ImgTitelBad: {
        width:270,
        height:4
      },
      clickImgBad: {
        width: (winWidth - 30)/2 ,
        height: (winWidth - 30)/2
      },
      rowBad: {
        width:13,
        height:12
      },
      showPicTitelBoxBad: {
        height:50,
        alignItems:'center',
        justifyContent:'center'
      },
      allDataBad: {
        height:44,
        width:winWidth-20,
        justifyContent:'center',
        alignItems:'center'
      },
      dialogContentBad: {
        position:'relative',
        paddingBottom:70,
        justifyContent: 'center',
        alignItems: 'center'
      },
      dailogTopBoxBad: {
        height:900 * imgScale,
        width:winWidth-40,
        borderRadius:4,
        backgroundColor:'#fff'
      },
      dailogImgStyleBad: {
        height:700 * imgScale - 20,
        width:'100%'
      },
      dailogTextBoxBad: {
        flex:1,
        height:100,
        flexDirection:'row',
        justifyContent:'center',
        alignItems:'center'
      },
      shareBoxBad: {
        borderColor:'#ff674b',
        marginLeft:10,
        backgroundColor:'#ff674b'
      },
      closeBtnLeftBad: {
        backgroundColor:'#fff',
        width:30,
        height:1,
        transform:[{rotate:'45deg'},
        {translateY:1},{translateX:1}]
      },
      closeBtnRightBad: {
        backgroundColor:'#fff',
        width:30,
        height:1,
        transform:[{rotate:'-45deg'}]
      }
})

相关文章

网友评论

    本文标题:react-native 编写的一个点击展开,下拉刷新案例

    本文链接:https://www.haomeiwen.com/subject/ujxnrxtx.html