转载需注明出处:http://blog.csdn.net/minimicall?viewmode=contents
从今天起,我要分析React Native for Android的源码。
本系列主要是从使用和源码分析的角度来一步步的剖析React Native Android。当然,因为我对IOS不了解,所以,我只能分析安卓了。
首先来一个Hello world。
对于Rn 安卓的开发环境,本着不重复造轮子的思想,我就不再这里介绍了。
1、 创建一个工程
首先,我们需要创建一个Rn工程,通过如下命令:
react-native init AweSomeProject
然后我们进入到该工程目录下。选择android目录:
确认里面有build.gradle文件。我们可以通过react-native run-android 来运行安卓程序。但,为了后续开发,我们选择使用AndroidStudio来打开。
在import project的时候,选择该android目录。然后就导入了工程。等待漫长的gradle更新过程吧,这个时候貌似在天朝需要vpn吧。
等待完了之后,点击run,运行程序,我们假设你已经有创建一个虚拟手机了,在电脑上。因为真机的话,我们后面再讲。因为它有点复杂。
这个时候你可以看到其实手机上已经有了效果。
2、MainActivity分析
这个时候,项目已经默认创建了一个MainActivity。我们来分析一下它的源码:
public class MainActivity extends ReactActivity { /** * Returns the name of the main component registered from JavaScript. * This is used to schedule rendering of the component. */ @Override protected String getMainComponentName() { return "AwesomeProject"; } /** * Returns whether dev mode should be enabled. * This enables e.g. the dev menu. */ @Override protected boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; } /** * A list of packages used by the app. If the app uses additional views * or modules besides the default ones, add more packages here. */ @Override protected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new ToastReactPackage() ); } }
英文注释已经解释的非常明白了。其实,我们定制模块最重要的是在getPackages()方法加上自己需要注册的模块。例如,我这里就注册了ToastReactPackage。这个等会说。
3、 index.android.js 文件
我们回过头来说js文件。打开这个文件,已经有了默认的。但我并不满足于它,我做一个简单的相册吧。
/** * Sample React Native App * https://github.com/facebook/react-native */ 'use strict'; import React, { AppRegistry, Component, StyleSheet, Text, View, Image } from 'react-native'; import KankanToast from './androidview/ToastAndroid'; var imgs = [ 'http://www.ituring.com.cn/bookcover/1442.796.jpg', 'http://www.ituring.com.cn/bookcover/1668.553.jpg', 'http://www.ituring.com.cn/bookcover/1521.260.jpg' ]; var MyImage = React.createClass({ getInitialState:function(){ return {imgs:imgs,count:0}; }, goNext:function(){ var count = this.state.count; count ++ ; if(count < imgs.length){ this.setState({ count:count }); } }, goPreview:function(){ var count = this.state.count; count --; if(count >= 0){ this.setState({count:count}); } }, render:function(){ return ( <View style={styles.flex}> <View style={styles.image}> <Image style = {styles.img} source = {{uri:this.state.imgs[this.state.count]}} resizeMode="contain" /> </View> <View style={styles.btns}> <TouchableOpacity onPress={this.goPreview}> <View style={styles.btn}> <Text>Prev</Text> </View> </TouchableOpacity> <TouchableOpacity onPress={this.goNext}> <View style={styles.btn}> <Text>Next</Text> </View> </TouchableOpacity> </View> </View> ); } }); KankanToast.show('这是一个Toast',KankanToast.SHORT); class AwesomeProject extends Component { render() { return ( <View style={styles.container}> <MyImage></MyImage> </View> ); } } const styles = StyleSheet.create({ container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#F5FCFF', }, welcome: { fontSize: 20, textAlign: 'center', margin: 10, }, instructions: { textAlign: 'center', color: '#333333', marginBottom: 5, }, image:{ borderWidth:1, width:300, height:200, borderRadius:5, borderColor:'#ccc', justifyContent:'center', alignItems:'center' }, img:{ height:150, width:200 }, btns:{ flexDirection:'row', justifyContent:'center', marginTop:20 }, btn:{ width:60, height:30, borderColor:'#0089FF', borderWidth:1, justifyContent:'center', alignItems:'center', borderRadius:3, marginRight:20 } }); AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
迫不及待的我们先来看一看效果:
弹了个Toast,你看,是不是和安卓原生态的一个墨阳。哎呀,模样。其实,墨阳这个名字真好听。
然后,就出来了我们期待的相册。是不是丑了点,将就着看吧,你行你上,不行别逼逼。
我们来分析一下这个源码的意思。
这段代码就是js的全部代码。我们来说明一下代码的含义。
1)导入:
import React, {
AppRegistry,
Component,
StyleSheet,
Text,
View,
Image
} from 'react-native';
上面是从react-native库里面导入对应的模块
import KankanToast from './androidview/ToastAndroid';
这个有意思了,这个是从当前目录下的androidview子目录下导入ToastAndroid模块。其实就是./androidview/ToastAndroid.js文件。它的内容我们后面再说
2、定义个数组
var imgs = [
'http://www.ituring.com.cn/bookcover/1442.796.jpg',
'http://www.ituring.com.cn/bookcover/1668.553.jpg',
'http://www.ituring.com.cn/bookcover/1521.260.jpg'
];
这个数组用来存储图片路径。
3、定义一个UI控件
var MyImage = React.createClass({...});
这个就是我们威名远扬的相册控件。
4、弹出一个Toast
KankanToast.show('这是一个Toast',KankanToast.SHORT);
看清楚,我用的是KankanToast,这个是我自己定义的一个组件。至于为什么要叫KankanToast,主要是曾老师是迅雷看看的一名资深开发屌丝。
当然,我们改名了,改成响巢看看,响巢看看,响巢看看。重要的事情说三遍,要是没记住,我就送你一张爱奇艺的会员卡了,对是爱奇艺的。
5、程序的入口组件
class AwesomeProject extends Component
这个里面有个render函数,注意它的根节点只能有一个<View>
6、定义css样式
const styles = StyleSheet.create
这个就不用多说了。
7、注册程序入口组件
AppRegistry.registerComponent('AwesomeProject', () => AwesomeProject);
到这里我们把js的代码说完了。回过头,我们得说说我们的KankanToast是怎么个回事。
当然,你最好把它注释掉。因为,我下篇再讲,今天太晚了,要睡觉了。不要问为什么,我工资低,比较任性。
晚安。下一篇,自定义控件。