初探React-Native(二)代码篇

撸了几天代码,iOS项目中集成RN页面还算简单,主要是互相之间的通讯,现在开始撸代码啦,
直接上干货!

1.iOS项目于RN之间互相的通讯

iOS向RN页面发送数据,只能发送字典奥!!!

iOS向RN页面发送数据

在RN界面接收后就可以直接使用啦!


接收并使用

RN向iOS发送数据

iOS项目中先创建一个类,并继承协议


.m文件

.h文件

在RN文件中,声明NativeModules


NativeModules声明

其中CalendarManager要和iOS项目的类名一模一样!


发送字符串

之所以发送加载结束是因为我在iOS项目中添加了HUD蒙版,等RN页面的数据加载完成之后,发送加载结束给iOS项目,然后清除蒙版,但是这里有个小坑,下文说

发送字典数据

这样就可以RN传值给iOS了,大家可以试一试,好了,现在要说一下坑了,由于本人懒癌发作,脑抽的没有新建类,而是直接在ViewController中直接继承了协议,机智的我发现一样可以NSLog()打印出数据,然后我就直接操作 [HUD removeFromSuperview]; 发现取消不了HUD,打印HUD发现为null!

可以接收数据,但是并改不了样式,哪怕加主线程

谷歌到的原因
解决方式还是老老实实的新创建类,然后用通知的方式进行更改吧

image.png

要放在主线程中奥!

2.RN中的列表ListView,包括下拉刷新上拉加载和网络请求

import React, { Component } from 'react';
import {
  AppRegistry,
  StyleSheet,
  View,
  Image,
  ListView,
  Text,
  TouchableOpacity,
  AlertIOS,
  NativeModules,
  RefreshControl,
  ActivityIndicator,
  Dimensions
} from 'react-native';

// 与iOS端通讯
var CalendarManager = NativeModules.CalendarManager;

// 声明空数组
var demoList = [];

// 获取全屏宽和高
var {width, height} = Dimensions.get('window');  


class ZhongShiMedia extends Component {


  constructor(props) {
    super(props);
    var ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});

    this.state = {
      dataSource: ds.cloneWithRows(demoList),
      bigImg:'',
      page:0,
      isLoadingTail: false,  //是否显示下拉加载的动画,没有数据了返回ture择不显示下拉动画
      isRefreshing: false,  // 是否隐藏上拉
      first:false,  //因为第一次进入时_endReached也会走,为false让他第一次不执行网络请求方法
    };

    this.fetchData(false);

  }



  render() {


    return (
     

      this._renderFooter()}   //尾视图用来显示加载图标
        onEndReachedThreshold={1}      //显示尾视图就执行加载
        onEndReached={() => this._endReached()}

        refreshControl={
           this._onRefresh()}/>
          }

          />         
          
          )

  }
  fetchData(isLoadMore) {

    if (isLoadMore) {
    // 加载
    this.state.page = this.state.page + 1;
}else{

    //刷新
  this.state.page = 1;

}



let  page = this.state.page ;

console.log('++++++' + page);

//网络请求方法
let url = 'http://pulandian.crhclub.com/attractionWebService.ashx?action=getAttractionInfoListRenqi&pageSize=10&page=' + page ;
fetch(url, {
  method: 'GET',
  headers: {},
})

.then((response) => response.json())
.then((responseData) => {

// 如果有数据
  if (responseData.zhihuijinshi.length != 0) {

   if (isLoadMore) {
    // 加载
  demoList = demoList.concat(responseData.zhihuijinshi);

}else{

    //刷新
  demoList = [];
  demoList = demoList.concat(responseData.zhihuijinshi);

}
}else{
  // 没有数据后,就不在执行下拉刷新的动画
  this.setState({
    isLoadingTail: true
  });
}

//修改数据和UI
this.setState({

 dataSource: this.state.dataSource.cloneWithRows(demoList),

 bigImg:responseData.advert[0].imgUrl,
 isRefreshing: false,

});
//发送iOS端,取消HUD的动画
CalendarManager.addEventOne('加载结束')

})

.catch((error) => {
  callback(error);
});


}


// 上拉刷新的方法
_onRefresh = () => {

 this.setState({
  isRefreshing: true,
});
 this.fetchData(false);
}

//下拉刷新的方法
_endReached = () => {
    // 防止第一次执行
    if(!this.state.first) {
     this.setState({
      first: true,
    });
     return
   }
    // 获取数据
    this.fetchData( true);
  }



  _renderFooter = () => {

    //没数据了则不显示动画
    if(this.state.isLoadingTail == true) {

     return 
   }

    // 加载动画
    return ();
  }


// 头视图
  _renderHeader(){
    return (  );
  }

// cell  的布局
  _renderRow(rowData, sectionid, rowid) {  
    return (
     {CalendarManager.addEventTwo({Id:rowData.id,title:rowData.title})}}>  
     

      

     

     {rowData.title}
     {rowData.address}

     
     
     
       
     );  
  }  


}



 const styles = StyleSheet.create({
    container: {   //根View样式
      marginTop:64,
      flex: 1,
        backgroundColor: '#F6F6F6'
      },
      imageeee:{

        height:100,

        marginLeft:15,
        marginTop:10,
        flex:0.4,
        backgroundColor: '#63BAE0'
      }, 

      rightSty:{
        flex:0.6,
        backgroundColor: '#F6F6F6'

      },


      hadImg:{

        flex:1,
        height:150,
        resizeMode:'stretch',
      },

      titleSty:{
        marginTop:10,
        marginLeft:15,
        width:width * 0.5,
        height:20,
        fontSize: 17,

      },
      addressSty:{
        marginTop:10,
        marginLeft:15,
        width:width * 0.5,

      },
      xian:{
        width:width,
        height:1,
        backgroundColor:'#272822',
        marginTop:10,
      },

      itemLayout:{  
        flex:1,  
        flexDirection:'row',
        flexWrap:'wrap',
    backgroundColor:'#F6F6F6',
  }, 

});



//  项目名要有所对应
AppRegistry.registerComponent('ZhongShiMedia', () => ZhongShiMedia);

(xianView那个就是创建一条线,可以用 borderStyle:'solid',
borderBottomWidth:1,
borderBottomColor:'gray', 这个属性替代,不要像我一样low,这些代码可复制粘贴直接使用,备注写的也还可以,喜欢给点个赞,如果有问题,可以联系我)

以下是个人理解的RN布局

RN布局主要是操作父类,在一个中View是父类,通过样式代码控制其子类是横向布局还是纵向布局
flexDirection:column 纵向 row 横向
然后可以再里面在通过另一个来重新控制其横向还是纵向,但是必须是View,ScrollView行不行没有试,不过是不行的
不过其子类可以用alignSelf这个属性
RN中没有css的浮动属性,不过有绝对定位和相对定位

3.RN中加载webView


              
                
              

搞完了iOS中集成RN布局,又玩了会纯RN项目,这个RN项目也是好多坑呀!!!我捞干的长话短说吧

1.tabBar项目框架的搭建

首先RN要集成一些第三方框架,而RN的关于tabBar的框架有TabNavigator和react-navigation
安装第三方框架的方法

安装:npm install react-navigation --save
查看:npm view react-navigation
删除:npm rm react-navigation --save

安装TabNavigator

npm install react-native-tab-navigator --save

安装react-navigation

npm install react-navigation --save

为什么要安装第三方框架呢,因为第三方框架安卓和iOS可以通用!
以上两个框架我都试了,我推荐使用react-navigation,因为到二级页面后他可以隐藏tabBar,
而TabNavigator没有隐藏的方法,只能动态改变TabBar的高度,也可能是我的方法有问题,才导致以下的Bug


如果有解决方法告诉我一下

react-navigation框架的集成....懒癌又犯了!主要是集成的代码太多,涉及多个页面,Demo还没写好,想要的留言吧,或者加我QQ1002547276,可以发个小项目给你

这是集成的部分代码

2.RN中创建轮播图
RN中主流的轮播图框架也有两个react-native-swiper 和 react-native-viewpager

这两个框架我同样都集成了,先说react-native-viewpager
安装react-native-viewpager

  npm install react-native-viewpager --save

项目中导入import ViewPager from 'react-native-viewpager';


image.png

但是这时候运行你会发现可恶的红色出现了
unddefined is not an object(evaluating ‘React.propTypes.func’)

4CB009D5DC235BB97D8FE345EB7F68AD.png

因为...有个库不用了,详情自己百度吧,这不重要,俺们来干的,上解决办法

进入到他的代码位置


image.png
ViewPager.js文件修改
DefaultViewPageIndicator.js文件修改
DefaultViewPageIndicator.js文件修改

这样就解决啦,可以畅快的用react-native-viewpager了
集成代码

import React, { Component ,PropTypes} from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Dimensions,
  Image
} from 'react-native';
import ViewPager from 'react-native-viewpager';

var deviceWidth = Dimensions.get('window').width;

var BANNER_IMGS = [
  'https://images.unsplash.com/photo-1441742917377-57f78ee0e582?h=1024',
  'https://images.unsplash.com/photo-1441716844725-09cedc13a4e7?h=1024',
  'https://images.unsplash.com/photo-1441448770220-76743f9e6af6?h=1024',
  'https://images.unsplash.com/photo-1441260038675-7329ab4cc264?h=1024',
  'https://images.unsplash.com/photo-1441126270775-739547c8680c?h=1024',
  'https://images.unsplash.com/photo-1440964829947-ca3277bd37f8?h=1024',
  'https://images.unsplash.com/photo-1440847899694-90043f91c7f9?h=1024'
];

export default class HomePage extends Component {

  constructor(props) {  
        super(props);  
        // 用于构建DataSource对象  
        var dataSource = new ViewPager.DataSource({  
            pageHasChanged: (p1, p2) => p1 !== p2,  
        });  
        // 实际的DataSources存放在state中  
        this.state = {  
            dataSource: dataSource.cloneWithPages(BANNER_IMGS)  
        }  
    }  
  
    _renderPage(data, pageID) {  
        return (  
              
        );  
    }  


  render() {
    return (
              

     
                                  


    );
  }

}


var styles = StyleSheet.create({

    container: {  
        flex: 1,  
        flexDirection: 'row',  
        alignItems: 'flex-start',  
        backgroundColor:'#999999',  
    },  
    page: {  
        width: deviceWidth,//设备宽(只是一种实现,此处多余)  
        height: 130,  
        resizeMode: 'stretch'  
    },  


});


你以为这就结束了? 不!!!


小点点有问题

这个控件的page点有问题,看到这一通集成的我已经崩溃了,不过可以在样式中添加renderPageIndicator={false} 来隐藏点点,不过我已经放弃这个控件了,如果有解决方法请留言或者私聊我!

下面就来看看react-native-swiper,首先先来说我为什么没有第一个选择这个框架,因为百度查到的react-native-swiper的资料都是


image.png
image.png

可以看出来,他们都是固定写死个数的,实际开发中,要根据后台返回的数据来创建不同个数,所有就要根据后台传的数组,动态创建

动态创建控件

有了这个,剩下的就简单啦

安装 react-native-swiper

npm i react-native-swiper --save

import React, { Component ,PropTypes} from 'react';
import {
  AppRegistry,
  StyleSheet,
  Text,
  View,
  Dimensions,
  Image
} from 'react-native';
import Swiper from 'react-native-swiper';

var deviceWidth = Dimensions.get('window').width;

var BANNER_IMGS = [
'https://images.unsplash.com/photo-1441742917377-57f78ee0e582?h=1024',
'https://images.unsplash.com/photo-1441716844725-09cedc13a4e7?h=1024',
'https://images.unsplash.com/photo-1441448770220-76743f9e6af6?h=1024',
'https://images.unsplash.com/photo-1441260038675-7329ab4cc264?h=1024',
'https://images.unsplash.com/photo-1441126270775-739547c8680c?h=1024',
'https://images.unsplash.com/photo-1440964829947-ca3277bd37f8?h=1024',
'https://images.unsplash.com/photo-1440847899694-90043f91c7f9?h=1024'
];

export default class HomePage extends Component {

  constructor(props) {  
    super(props);  

        // 实际的DataSources存放在state中  
        this.state = {  
        }  
      }  


      render() {

       var images = [];

       for (var i = 0; i < BANNER_IMGS.length; i++) {
        let view = (

          
            
            

          )

        images.push(view);
      }


      return (
        

        
                   {images}
                   

                   

                   );

    }
  }


  var styles = StyleSheet.create({

    lalal:{
      height:200,
      width:deviceWidth,

      backgroundColor:'#FEFEFE',  

    },
    slide: {
      flex: 1,
      justifyContent: 'center',
      alignItems: 'center',
      backgroundColor: '#9DD6EB'
    },
    page: {
      color: '#fff',
      width:deviceWidth,
      height:150,
    }

  });


这两天撸的代码都在这里啦,RN之路还在慢慢探索中,有什么问题欢迎打扰,一起探讨

生命不息,代码不止!码农一枚,请多点赞

你可能感兴趣的:(初探React-Native(二)代码篇)