当前位置: 代码迷 >> Android >> React Native Android入门实战及深入源码分析系列(一)——Hello world
  详细解决方案

React Native Android入门实战及深入源码分析系列(一)——Hello world

热度:231   发布时间:2016-04-24 11:31:55.0
React Native Android入门实战及深入源码分析系列(1)——Hello world

转载需注明出处: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是怎么个回事。


当然,你最好把它注释掉。因为,我下篇再讲,今天太晚了,要睡觉了。不要问为什么,我工资低,比较任性。

晚安。下一篇,自定义控件。




  相关解决方案