一篇搞懂React-Native
一篇搞懂React-Native
前言
提示:一篇针对RN项目开发的速成笔记,拥有它轻松掌握React-Native项目开发。
1、在项目目录中打开Powershell
2、在Powershell命令行中输入 初始化项目命令(使用react-native-cli):react-native init <项目名称>
3、先要数据线链接手机或者打开模拟器
4.检查设备链接情况(先要链接手机并打开开发者模式或者打开模拟器)
5.进入项目目录 运行
react-native run-android
已启动项目
6.项目建设
6.1.导入注册插件使用的AppRegistry import {AppRegistry} from ‘react-native’
6.2.导入组件 MyHomePageApp——组件 import MyHomePageApp from ‘路径’ /组件 只能使用.js后缀的文件
a.在RN中,不能使用网页中的所有标签,像div,p,img不能用
b.RN提供View来实现布局,需要的组件从'react-native'中导入 import {View,Text} from 'react-native' 具体见文档-组件
c.在RN中,所有文本,必须使用RN提供的Text组件进行包裹,否则会报错
d.Platfrom 平台检测const instructions = Platfrom.select({ }); StyleSheet 样式相关组件,专门用来创建样式的 const styles = StyleSheet.create({ })
e.Image 组件 <Image source={ repuire('本地路径') or {uri:'url地址'} }></Image>
f.Button组件和ActivityIndicator组件
g.ScrollView组件和flatList组件
h.tab栏需安装 react-native-tab-navigator 包 使用见文档UI https://github.com/ptomasroos/react-native-tab-navigator
i.icon图标推荐使用 react-native-vector-icons 包 安装环境步骤见文档 https://github.com/oblador/react-native-vector-icons
(1)装包,
(2)编辑 android/app/build.gradle文件,增加一下内容(带+号标记需增加项)
... ...
import com.android.build.OutputFile
+ project.ext.vectoricons = [ iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf' ,'FontAwesome.ttf' ] // Name of the font files you want to copy
]
+ apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
,并启用FontAwesome.ttf字体文件库,修改iconFontNames: [ 'MaterialIcons.ttf', 'EvilIcons.ttf' ,'FontAwesome.ttf']
(3)复制react-native-vector-icons包中Fonts文件内容至android/app/src/main/assets/fonts
(4)编辑android/settings.gradle ,增加一下内容(带+号标记需增加项)
+ include ':react-native-vector-icons'
+ project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
(5)编辑android/app/build.gradle,增加一下内容(带+号标记需增加项)
dependencies {
...
implementation "com.facebook.react:react-native:+" // From node_modules
+ compile project(':react-native-vector-icons')
}
(6)编辑 android/app/src/main/java/...MainApplication.java,增加一下内容(带+号标记需增加项)
package com.myapp;
+ import com.oblador.vectoricons.VectorIconsPackage;
....
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage()
+ , new VectorIconsPackage() ***安装 Android SDK License 29.0.1 后此步可省略
);
}
(7)' 需要安装Android SDK License 26.0.1 //***安装 Android SDK License 29.0.1 后此步可省略
(8)import Icon from 'react-native-vector-icons/FontAwesome';
const myIcon= <Icon name="rocket" size={30} color="#900" />;
j.swiper轮播图推荐使用 react-native-swiper 包 安装步骤见文档: https://github.com/leecade/react-native-swiper
* 轮播图的外面必须加一个有高度的外套View,需要自动轮播 autoplay=true loop=true,见文档 *
k.九宫格布局注意手机默认是纵向流式布局,要改变方向 flexDirection:'row',flexWrap:'wrap'
l. router 路由推荐使用 react-native-router-flux 包及所需依赖包 安装步骤见文档: https://github.com/aksonov/react-native-router-flux
* Router相当于React中的HashRouter
* Stack 是一个分组的容器,它不表示具体路由,专门用来给路由分组,路由规则 Scene 都要放在 Stack 中;
* Scene 就表示一个具体的路由规则,好比React中的Route,其属性有key,component,title,path,hideNavBar,...; key是编程式导航需要的,路由规则具有唯一性;component 为导航去到的目标组件;hideNavBar 是否隐藏导航栏;
(1)装路由包及依赖包:yarn add react-native-router-flux react-native-screens react-native-gesture-handler react-native-reanimated react-native-safe-area-context @react-native-community/masked-view
(2)引入路由包组件,创建导航目标组件和路由规则:
import { Router , Stack , Scene } from 'react-native-router-flux'
<Router sceneStyle={{backgroundColor:'#FFFFFF'}}>
<Stack key="root">
<Scene key="app" component={App} title="这是App组件" hideNavBar/>
<Scene key="movielist" component={MovieList} title="热映电影列表" hideNavBar={false} />
</Stack>
</Router>
(3)使用react-native提供的TouchableHighlight 控件包裹需要点击的唯一DOM元素,可接收元素的style,并增加 underlayColor='white' 点击时背景色为'white' ,如:
<Scene style={styles.box} key="movielist" component={MovieList} title="热映电影列表" hideNavBar={false} /> 中的 key="movielist";
(4)在TouchableHighlight 控件上使用onPress事件,引入react-native-router-flux的Actions进行编程式导航,Actions即表示进行JS的路由操作,如:
View/:
<TouchableHighlight style={styles.box} onPress={this.goMovieList} underlayColor='white'>
<View >
<Image source={require('../../images/menu5.png')} sytle={{height:60,width:60}}></Image>
<Text style={{fontSize:20}}>热映电影</Text>
</View>
</TouchableHighlight>
js/: goMovieList=()=>{ Actions.movielist() } //movielist是路由规则中Scene唯一的key值
m.数据请求使用 fetch('API').then((res)=>res.json()).then((data)=>console.warn(data)) data即请求回来的数据,可保存在state中;
n. 使用React-native的组件 Flatlist 对电影列表进行展示, 见文档:https://reactnative.cn/docs/flatlist ,如
//渲染电影列表
renderList=()=>{
if(this.state.isLoading){
return <ActivityIndicator size='large' color="#ccc"></ActivityIndicator>
}
return <View>
<SafeAreaView>
<FlatList
// horizontal
style={{backgroundColor:'white'}}
data={this.state.movies}
ItemSeparatorComponent={this.renderSeparator} //渲染分割线
renderItem={({item})=> this.renderItem(item)} //渲染电影列表,注意{item,index,sparator}需要引用
keyExtractor={item => item.id}
onEndReachedThreshold={0.5}
onEndReached={this.loadNextPage}
/>
</SafeAreaView>
</View>
}
//渲染每一项
renderItem=(props) => (
<TouchableHighlight
onPress={() =>this.goMovieInfo({id:props.id})}
// onShowUnderlay={separators.highlight}
// onHideUnderlay={separators.unhighlight}
underlayColor='white'
style={{backgroundColor: 'white',
padding: 10, marginVertical: 10,marginHorizontal: 10,
alignItems:'center'}}
>
<View style={{width:'100%',flexDirection:'row'}}>
<Image source={{uri:props.images.small}} style={{height:220,width:160}}></Image>
<View style={{paddingHorizontal:20,justifyContent:'space-around',flex:1}}>
<Text style={{fontSize:22}}>电影名称:<Text>{props.title}</Text></Text>
<Text style={{fontSize:22}}>电影类型:<Text>{props.genres}</Text></Text>
<Text style={{fontSize:22}}>制作年份:<Text>{props.year}年</Text></Text>
<Text style={{fontSize:22}}>豆瓣评分:<Text>{props.rating.average}分</Text></Text>
</View>
</View>
</TouchableHighlight>
)
//渲染分割线
renderSeparator=()=>{
return <View style={{borderTopWidth:1,borderColor:'#ccc',marginHorizontal:20}}></View>
}
//加载更多
loadNextPage=()=>{
if(this.state.nowPage + 1 > this.state.totalPage){return}
this.setState({
nowPage:this.state.nowPage +1
},this.getMoviesByPage())
}
// 带参数导航 去到电影详情页面
goMovieInfo=(props)=>{
Actions.movieinfo(props)
}
6.3.AppRegistry.registerComponent(‘项目名称’,()=>App)
7.调用手机摄像头(带+号标记需增加项)
(1) 摄像头栏需安装 react-native-image-picker 包 使用见文档 https://github.com/react-native-image-picker/react-native-image-picker/
(2) 运行 react-native link 自动注册相关组件到原生配置中;
(3) 打开 ./android/app/src/main/AndroidManifest.xml 文件,添加以下内容:
<uses-permission ... />
+ <uses-permission android:name="android.permission.CAMERA" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
(4) 在项目中添加如下代码:
//第一步
import {launchCamera} from 'react-native-image-picker';
//创建拍照时的配置对象
var photoOptions = {
//底部弹出框选项
title: '请选择',
cancelButtonTitle:'取消',
takePhotoButtonTitle:'拍照',
chooseFromLibraryButtonTitle:'选择相册',
quality:0.75,//拍照质量0-1
allowsEditing:true,
noData:false,//拍照时不带日期
storageOptions:{
skipBackup:true, //跳过备份
path:'images'
},
saveToPhotos:true,//(布尔值)仅适用于launchCamera,将捕获的图像/视频文件保存到公共照片
mediaType:'photo',//如果是 'video',详见文档 https://github.com/react-native-image-picker/react-native-image-picker/#note-on-file-storage
maxWidth:300,
maxHeight:300,
cameraType:'front',
}
//第二部
constructor(props){
super(props);
this.state={
imgURL:''
}
}
//第三步
render(){
return <View style={{alignItems:'center',paddingTop:200}}>
<Image source={{uri:this.state.imgURL}} style={{width:200,height:200,borderRadius:100}}></Image>
<Button title='拍照' onPress={this.cameraAction}></Button>
</View>
}
//第四步
cameraAction = ()=>{
launchCamera(photoOptions, (response)=>{
console.warn('response'+response);
if(response.didCancel){
return
}
this.setState({
imgURL:response.uri
})
})
}
8.签名打包发布Release版本的APK安装包 参考网页文档:(带+号标记需增加项)
8.1 https://www.jianshu.com/p/1380d4c8b596
8.2 https://blog.csdn.net/fengyuzhengfan/article/details/51958848
(1) 正确配置所有RN环境
(2) 在CMD命令行中,运行这句话:keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
其中:my-release-key.keystore 表示你要生成的签名文件名称,需要保存记录;
-alias 参数后面的别名是你将来为应用签名时所需要用到的,所以也需要保存记录;
当运行这个命令的时候,需要输入一系列的参数,及口令的密码,是**,很重要,也需要保存记录;
(3)当生成了签名之后,my-release-key.keystore这个签名文件存放在 C:\Users\wuyaohua> 中;
(4) 设置gradle变量
a.将你的签名证书copy到 android/app目录下;
b.编辑~/.gradle/gradle.properties或…/android/gradle.properties(一个是全局gradle.properties,一个是项目中的gradle.properties,大家可以根据需要进行修改) ,加入如下代码:
MYAPP_RELEASE_STORE_FILE=your keystore filename
MYAPP_RELEASE_KEY_ALIAS=your keystore alias
MYAPP_RELEASE_STORE_PASSWORD=*****
MYAPP_RELEASE_KEY_PASSWORD=*****
提示:以上用正确的证书密码、alias以及key密码替换掉 。
(5) 在gradle配置文件中添加签名配置
编辑 android/app/build.gradle文件添加如下代码:
...
android {
...
defaultConfig { ... }
signingConfigs {
+ release {
+ storeFile file(MYAPP_RELEASE_STORE_FILE)
+ storePassword MYAPP_RELEASE_STORE_PASSWORD
+ keyAlias MYAPP_RELEASE_KEY_ALIAS
+ keyPassword MYAPP_RELEASE_KEY_PASSWORD
}
}
buildTypes {
release {
...
+ signingConfig signingConfigs.release
}
}
}
...
(6) 签名打包APK
进入项目根目录下的android文件夹打开终端输入: ./gradlew assembleRelease
(7) 签名打包成功后你会在 “android/app/build/outputs/apk/”目录下看到签名成功后的app-release.apk文件。
提示:如果你需要对apk进行混淆打包 编辑android/app/build.gradle:
/**
* Run Proguard to shrink the Java bytecode in release builds.
*/
def enableProguardInReleaseBuilds = true
adb devices
总结
本文是作者亲自整理,如对你有帮助,请收藏转发并尊重原创,谢谢! ——corder吴
上一篇: JSON Web Token
下一篇: 重复读取inputStream