2016-10-10 14:46:29 c670080507 阅读数 1135
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

React-Native的库的更新是非常的频繁的。

所以我们首先要知道当前使用的React-Native的版本是多少。

怎么获取到当前的版本号呢?

有两种方法:

1.是通过进入项目的根目录,打开package.json文件


可以看到当前使用的react-native的版本号。

2.是使用命令行工具

同上也是进入当前项目的根目录。

输入react-native --version命令就可以获取到当前的版本号。


那么怎么获取到当前的react-native的版本号的信息呢?
可以通过输入命令npm info react-nartive
获取到npm上面的react-native库的列表。


获取到版本号之后怎么对当前项目使用的react-native版本进行管理呢

可以使用命令行

npm install --save react-native@0.34.0

@0.34.0代表你想改变当前的项目使用的react-native的版本号,版本号通过刚刚 npm info react-native 获得。

然后就可以改变版本号了


2018-02-12 10:37:38 u011562187 阅读数 1191
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

我的环境:
react 16.0.0
react-native 50.0.3

升级为当前最新版:

react 16.2.0
react-native 53.0.0

升级部分可按中文官网教程进行,
1.npm info react-native 查看最新RN版本,修改package.json 中dependencies的react-native 版本为最新(53.0.0).
2.react 版本(中文官网原话:从0.24版本开始,react-native还需要额外安装react模块,且对react的版本有严格要求,高于或低于某个范围都不可以。本文无法在这里列出所有react native和对应的react模块版本要求,只能提醒读者先尝试执行npm install,然后注意观察安装过程中的报错信息,例如require react@某.某.某版本, but none was installed,然后根据这样的提示,执行npm install react@某.某.某版本 –save。)

执行
npm install

关于升级项目模板文件

react-native upgrade

因为我改过原生代码,不执行这个,项目正常编译执行,执行后反而有问题,因为一不小心就把我修改过的文件给替换成模板文件了。
(所以感觉能不用就不用,真要用就做好备份。)

升级后的问题:

Error: While resolving module `react-native-vector-icons/XXX`, the Haste package `react-native-vector-icons` was found.

https://github.com/oblador/react-native-vector-icons/issues/626

react-native-vector-icons 4.4.3 => 4.5.0
解决方法:
删除
./node_modules/react-native/local-cli/core/__fixtures__/files/package.json

2019-12-03 11:46:10 weixin_45077505 阅读数 26
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

截屏组件react-native-view-shot,可以截取当前屏幕或者按照当前页面的组件来选择截取
兼容情况:
在这里插入图片描述

1、安装

yarn add react-native-view-shot

React Native 0.60.x之前的版本需要手动link,

react-native link react-native-view-shot

0.60.x之后会自动link,不过ios可能需要做些手动操作

cd ios && pod install && cd ..

2、使用高级API

现在官方推荐使用的高级API:
直接将组件导入当作标签使用:

import ViewShot from "react-native-view-shot";  // 这里的ViewShot就是要使用的标签的名字

下面的<ViewShot></ViewShot>所包裹的就是需要截图的区域,里面所有的元素都会被截下来

<ViewShot ref="viewShot" options={{ format: "jpg", quality:1 }}>
  <Text>...这里是截图区域,可以是任意显示元素...</Text> 
</ViewShot>

对应的取值方法
指定需要截取的组件的ref名称,然后调用capture()来截取指定组件的内容。如下,需要使用viewShot.capture()来进行截取:

this.refs.viewShot.capture().then(uri => {
  console.log("截图完成以后的操作 ", uri); // 这里的uri即为截取完成的图片,可以是本地文件、base64等等
});

补充options

标签上面使用到的options属性参数:

  • format:指定生成图片的格式pngjpgwebm (Android), 默认格式为png
  • quality:截取的图片质量,取值0.0 - 1.0 ,默认为1.0
  • result:最后生成的图片类型:tmpfilebase64data-uri
    1、tmpfile:临时文件(该文件仅在应用程序运行时才存在)。
    2、base64:编码为base64并返回原始字符串。仅适用于小图像。
    3、data-uri:与base64相同,还包含数据URI方案头。
  • width :指定最后生成的图片的宽度
  • height:指定最后生成的图片的高度

需要截取的区域有动态加载的图片时

需要在图片加载完以后再去进行截取:

class waitingCaptureDemo extends Component {
  onImageLoad = () => {
    this.refs.viewShot.capture().then(uri => {
      console.log("图片加载完成以后进行的截取 ", uri);
    })
  };
  render() {
    return (
      <ViewShot ref="viewShot">
        <Text>...截取区域..</Text>
        <Image ... onLoad={this.onImageLoad} />
      </ViewShot>
    );
  }
}

截取区域为ScrollView时

class captureScrollViewContentDemo extends Component {
  onCapture = uri => {
    console.log("ScrollView的完整内容截图 ", uri);
  }
  render() {
    return (
      <ScrollView>
        <ViewShot onCapture={this.onCapture} captureMode="mount">
          <Text>.这里是ScrollView的内容部分	</Text>
        </ViewShot>
      </ScrollView>
    );
  }
}

补充captureMode、onCapture、onCaptureFailure

captureMode
如果没有定义捕获模式,默认不是自动捕获的,需要使用ref并且调用capture();
取值:

  • mount:挂载后立即捕获视图
  • continuous:连续捕获很多图像
  • update:每次React重绘(更新时)时捕获图像

onCapture:当定义了captureMode时,使用这个回调获取捕获结果;
onCaptureFailure:当定义了captureMode时,如果捕获失败,则将调用此回调。

3、使用captureRef 低级API

import { captureRef } from "react-native-view-shot";

captureRef(viewRef, {
  format: "png",
  quality: 1
}).then(
  uri => console.log("这是需要保存的图片", uri),
  error => console.error("截取图片失败", error)
);

未完待续~~~~~~~~

2019-02-01 14:58:11 LQ0611 阅读数 2024
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

本模块讲述的是自动获取当前位置,并获取当前天气

 

思路:1.获取到当前位置;2.根据当前位置去获取天气

第一步:获取到当前位置

我这里用的是高德地图react-native-smart-amap-location这个组件获取当前位置

具体操作:

Android部分:

需要用到两个组件,

安装:

npm install react-native-smart-amap-location --save

npm install react-native-smart-app-event-listener-enhance --save

配置:

1.在 android\settings.gradle 中添加

include ':react-native-smart-amap-location'
project(':react-native-smart-amap-location').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-smart-amap-location/android')

2.在 android\app\build.gradle 中

dependencies {
    compile project(':react-native-smart-amap-location')//添加此行
    
}

3.在 MainApplication.java 中 添加

import com.reactnativecomponent.amaplocation.RCTAMapLocationPackage;//添加此行

.............

@Override
protected List<ReactPackage> getPackages() {
  return Arrays.<ReactPackage>asList(
      ..........
        new RCTAMapLocationPackage(),//添加此行
       .......
  );
}

4.在 AndroidManifest.xml 中添加权限

<!--*************************高德地图-定位所需要权限*************************-->
<!-- Normal Permissions 不需要运行时注册 -->
<!--用于访问wifi网络信息,wifi信息会用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--这个权限用于获取wifi的获取权限,wifi信息会用来进行网络定位-->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_CONFIGURATION" />

<!-- 请求网络 -->
<uses-permission android:name="android.permission.INTERNET" />

<!-- 不是SDK需要的权限,是示例中的后台唤醒定位需要的权限 -->
<!--<uses-permission android:name="android.permission.WAKE_LOCK" />-->

<!-- 需要运行时注册的权限 -->
<!--用于进行网络定位-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--用于访问GPS定位-->
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!--用于提高GPS定位速度-->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<!--写入扩展存储,向扩展卡写入数据,用于写入缓存定位数据-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!--读取缓存数据-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!--用于读取手机当前的状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

<!-- 更改设置 -->
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<!--*************************高德地图-定位所需要权限*************************-->

 并 在 application 中添加如下代码,并把从  高德地图API申请的key   填写到下面value处

<application
  。。。。。。。。
">
    <!-- 高德地图 -->
    <meta-data
            android:name="com.amap.api.v2.apikey"
            android:value="从高德地图API申请的key"/>

    <service android:name="com.amap.api.location.APSService" >
    </service>

</application>

可能出现的错误:

1.No resource found that matches the given name: attr 'android:keyboardNavigationCluster'

解决方法:

到相应组件的 android\bulid.gradle 中 ,改为26 及 26.0.1

compileSdkVersion 26
buildToolsVersion "26.0.1"

和 依赖也改为 26.0.1

dependencies {
    compile 'com.android.support:appcompat-v7:26.0.1'
}

2.在运行中可能出现一个在 node_modules\react-native-smart-amap-location\android\src\main\java\com\reactnativecomponent\amaplocation\RCTAMapLocationPackage.java  中 第22行  @Override  的错误,

此时需要将 这个方法删掉即可

例子代码:

import React, { Component } from 'react';
import {
    View, TextInput, Keyboard, Text, KeyboardAvoidingView, Image, StyleSheet, NetInfo, Platform, Alert,
    ImageBackground, ScrollView, DeviceEventEmitter, TouchableOpacity, StatusBar,
    NativeAppEventEmitter, ProgressBarAndroid, ActivityIndicator, Dimensions
} from 'react-native';
import { InputItem, Button, WingBlank, Toast, Checkbox, Modal } from 'antd-mobile-rn';
import AMapLocation from 'react-native-smart-amap-location';
import AppEventListenerEnhance from 'react-native-smart-app-event-listener-enhance'
const duration = 20000;

//fetch扩展,加入超时功能.
const fetchPlus = (url, config) => {
    let fetch_promise = fetch(url, config);
    let time_promise = new Promise((resolve, reject) => {
        setTimeout(() => {
            reject(new Error('请求超时'));
        }, duration);
    });
    return Promise.race([fetch_promise, time_promise]);
}
const width = Dimensions.get('window').width;

class Test extends Component {
    static navigationOptions = ({navigation,screenProps}) => ({
        // 这里面的属性和App.js的navigationOptions是一样的。
        header : null
    });
    constructor(props) {
        super(props);
        this.state = {
            addLoading:true,
            weaLoading:true,
            address:'',
            weather:'',
        };

    }
    async show(district){
        console.log("地区;",district);
        try{
            let url = `http://wthrcdn.etouch.cn/weather_mini?city=${district}`;
            let response = await fetchPlus(url);
            let result = await response.json();
            console.log("singleGetList result:",result);
            debugger;
            this.setState({
                weather:result,
                weaLoading:false,
            })
            return result;
        }catch (e){
            Toast.info('发生未知错误')
            this.setState({
                weaLoading:false,
            })
        }

    }
    componentDidMount() {

        AMapLocation.init(null);

        this._showReGeocode();

        this.addAppEventListener(
            NativeAppEventEmitter.addListener('amap.location.onLocationResult', this._onLocationResult)
        )
    }
    componentWillUnmount () {
        //停止并销毁定位服务
        AMapLocation.cleanUp()
    }
    //单次定位并返回逆地理编码信息
    _showReGeocode = () => {
        console.log("bbbbbbbbb");
        this.setState({
            loading: true,
        })
        AMapLocation.getReGeocode()
    }
     _onLocationResult = (result) => {
         this.setState({
             addLoading:false,
         })
        if(result.error) {
            Alert.alert(`错误代码: ${result.error.code}, 错误信息: ${result.error.localizedDescription}`)
        }
        else {
            if(result.formattedAddress) {
                console.log("地址:"+result.city+"-"+result.district);
                let r ='';
                if(result.district){
                     r= this.show(result.district);
                }else{
                     r= this.show(result.city);
                }
                this.setState({
                    address:result,
                    addLoading:false,
                })
            }
            else {
                Alert.alert(`纬度 = ${result.coordinate.latitude}, 经度 = ${result.coordinate.longitude}`)
            }
        }

    }
    showWeather(item,key){
        console.log("aaa")
        if(key!==0){
            return(
                <View key = {key}>
                    <View
                          style={{
                              width:width,
                              justifyContent:'space-between',
                              flexDirection:'row',
                              alignItems:'center',
                              height:40,
                              paddingLeft:10,
                              paddingRight:10,
                          }}>

                            <Text style={{fontSize:13}}>{item.date}</Text>

                            <Text style={{fontSize:13}}>{item.type}</Text>

                            <Text style={{fontSize:13}}>{item.high.split(' ')[1]+' / '+item.low.split(' ')[1]}</Text>

                    </View>
                    <View style={{height:1,width:width,backgroundColor:'#F5F5F5'}}/>
                </View>
            )
        }
    }

    render() {
        let address = this.state.address;
        let weather = this.state.weather;
        debugger
        return (
            <ScrollView style={{flex:1,backgroundColor:'#FFFFFF'}}>
                <View style={{flex:1}}>
                    {
                        this.state.addLoading?
                            <View sytle={{flex:1,justifyContent:'center',alignItems:'center',}}>
                            <ActivityIndicator size="large"/>
                                <Text>定位中......</Text>
                            </View>
                            :
                            <View sytle={{flex:1,justifyContent:'center',alignItems:'center',}}>
                                <Text style={{fontSize:30,color:'#333333'}}>{address!==''&&(address.city+"-"+address.district)}</Text>
                            </View>
                    }
                </View>
                <View sytle={{flex:6}}>
                    {
                        !this.state.weaLoading?
                            <View>
                                <View style={{height:80,justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{fontSize:45,color:'#333333'}}>{weather!==''&&weather.data.wendu+' ℃'}</Text>
                                </View>
                                <View style={{height:40,justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{fontSize:30,color:'#333333'}}>{weather!==''&&weather.data.forecast[0].type}</Text>
                                </View>
                                <View style={{height:40,justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{fontSize:20,color:'#666666'}}>{weather!==''&&weather.data.forecast[0].high.split(' ')[1]+' / '+weather.data.forecast[0].low.split(' ')[1]}</Text>
                                </View>
                                <View style={{height:40,justifyContent:'center',alignItems:'center'}}>
                                    <Text style={{fontSize:15,color:'#666666'}}>{weather!==''&&weather.data.forecast[0].fengxiang+weather.data.forecast[0].fengli.split(']')[0].slice(9)}</Text>
                                </View>
                                <View style={{height:40,justifyContent:'center',alignItems:'center',paddingLeft:10,paddingRight:10}}>
                                    <Text style={{fontSize:13,color:'#999999'}}>{weather!==''&&weather.data.ganmao}</Text>
                                </View>
                            </View>
                            :
                            <View style={{height:240,justifyContent:'center',alignItems:'center'}} >
                                <ActivityIndicator size="large"/>
                                <Text>正在获取天气......</Text>
                            </View>
                    }
                </View>
                <View sytle={{flex:1}}>
                    <View style={{width:width,height:1,backgroundColor:'#f5f5f5'}}/>
                    {
                        weather!==''&& weather.data.forecast.map((item,key)=> this.showWeather(item,key))
                    }
                </View>
            </ScrollView>
        );
    }
}

export default AppEventListenerEnhance(Test);
2019-11-21 11:21:39 weixin_44043810 阅读数 10
  • React Native 项目开发实战 第1节

    移动端应用高速发展, 本教程便是使用ReactNative开发的高性能基于原生应用跨Android与iOS两大平台的大型综合App。 本实战项目使用react native 开发招聘,房产,点餐,商城,二手车,本地商务的大型综合门户性app项目实战课程,项目基于RN最新版本0.58, react-navigation也是基于最新3.x版。在整个项目中使用到了mobx进行数据和状态管理,封装了很多原生模块例如 地图组件 react-native-mapbox-gl,聊天组件 react-native-gifted-chat等等,同时封装了大大小小30多个自定义组件包括FlatList再次封装, 数字键盘封装,自定义图标组件封装,表单验证组件的封装等。  本课程为项目实战的开篇课程,主要讲解ES6常用语法和概念的理解,包括箭头函数和静态方法的使用等为后续实战做好铺垫, 课程最后完成一个基于实战项目中的Tab标签组件的封装。

    482 人正在学习 去看看 钱兴岗

react-native-baidu-map@0.6.0 Xcode10.2 配置方法

当前环境
react-native 0.59.8
react-native-baidu-map 0.6.0
安装百度地图0.6.0
npm install react-native-baidu-map@0.6.0 --save
react-native link react-native-baidu-map
Xcode10.2配置libstdc++.6.0.9.tbd(百度地图0.6.0版本依赖此库,而Xcode10.2已经废弃)
首先下载版本9.4.1的xcode(这里我是用的9.4.1,网上说9.x以上版本都可以)
拷贝需要的文件
运行在设备上
将xcode9.4.1以下文件(libstdc++.6.0.9.tbd、libstdc++.6.tbd)复制到xcode10.2版本的当前文件中,以下是两者文件夹的路径
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk/usr/lib/
运行在模拟器上
将xcode9.4.1以下文件(libstdc++.dylib、libstdc++.6.dylib、libstdc++.6.0.9.dylib)复制到xcode10.2版本的当前文件中,以下是两者文件夹的路径
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/usr/lib/
将xcode9.4.1以下文件(libstdc++.6.0.9.tbd、libstdc++.6.tbd)复制到xcode10.2版本的当前文件中,以下是两者文件夹的路径
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/usr/lib/
至此xcode配置完毕
配置百度地图
首先对百度地图内部node_modules进行的修改配置
修改此文件下的代码,改变RCTBridgeModyle.h的引入方式为以下图示1所示
在这里插入图片描述

修改RCTViewManager.h/RCTConvert+CoreLocation.h的引入方式,如下图2所示
在这里插入图片描述

由于PropTypes的引入方式改变,注意安装组件prop-types,从此组件中引用PropTypes,注意找到百度地图组件关联的地方进行修改
在这里插入图片描述

其次对xcode进行配置
Build Settings->Search Paths, Framework search paths 添加 $(PROJECT_DIR)/…/node_modules/react-native-baidu-map/ios/lib
Header search paths 添加 $(SRCROOT)/…/node_modules/react-native-baidu-map/ios/RCTBaiduMap
添加依赖, react-native-baidu-map/ios/lib 下的全部 framwordk(位置如下图所示)
在这里插入图片描述

然后继续添加:CoreLocation.framework和QuartzCore.framework、OpenGLES.framework、SystemConfiguration.framework、CoreGraphics.framework、Security.framework、libsqlite3.0.tbd(xcode7以前为 libsqlite3.0.dylib)、CoreTelephony.framework 、libstdc++.6.0.9.tbd(xcode7以前为libstdc++.6.0.9.dylib)
接下来添加 BaiduMapAPI_Map.framework/Resources/mapapi.bundle,注意选择上Copy items if needed选项
在这里插入图片描述
在这里插入图片描述
AppDelegate.m init 初始化
#import “RCTBaiduMapViewManager.h”
[RCTBaiduMapViewManager initSDK:@“百度地图申请的ios的Key”];
代码中的书写方法
import { MapView } from ‘react-native-baidu-map’
<MapView
style={{width:‘100%’,height:300}}
zoom={15}
trafficEnaled={false}
baiduHeatMapEnabled={false}
setEsriLogoVisible={false}
mapType={1}
center={
{
longitude: 115.25,
latitude: 39.26
}
}>

在这里插入图片描述

没有更多推荐了,返回首页