{//********************************* React Native(前端) ***************************** Learn once , Write anywhere
官网: http://facebook.github.io/react-native/docs/getting-started.html
资源汇总: https://github.com/reactnativecn/react-native-guideJSX //js+xml -- js中嵌入html --> 避免js html的割裂(频繁查找dom元素),实现真正的组件化 
虚拟DOM //虚拟DOM和diff算法提高渲染性能 --> 提升性能{//=====================================环境安装============================ 
{//-----------------------------------本地开发调试---------------------- win10
 {//安装Android
 1. 安装Android (见前面H5跨平台)
 2. 设置环境变量 (win10 控制面板 -> 系统 -> 高级系统设置 -> 环境变量 -> 用户变量里点新建
 新建ANDROID_HOME变量 C:\Users\ivan\AppData\Local\Android\sdk 
 在PATH变量里新建 C:\Users\ivan\AppData\Local\Android\sdk\tools
 在PATH变量里新建 C:\Users\ivan\AppData\Local\Android\sdk\platform-tools

 3.重新打开命令提示符,测试是否OK
 > adb version //测试 成功会显示adb版本 
 > android //测试 成功会打开Android SDK Manager 表示环境变量设置成功
 } 


 npm install -g react-native-cli //install react native
 react-native init AwesomeProject
 cd AwesomeProject
 通过usb线连接Android手机
 react-native run-android /*成功会在手机上看到 Welcome to React Native
 报错: 一直在下载 gradle-2.4-all.zip
 解决方法: 把我们已下好的离线包gradle-2.4-all.zip放在对应目录,
 如C:\Users\ivan\.gradle\wrapper\dists\gradle-2.4-all\6r4uqcc6ovnq6ac6s0txzcpc0

 报错: build-tools 23.0.2
 在http://mirrors.neusoft.edu.cn/android/repository/下载build-tools_r23.0.2-windows.zip后,
 放在C:\Users\ivan\AppData\Local\Android\sdk\build-tools目录下,并解压 

 报错: > Could not find com.android.support:support-v4:23.2.1.
 解决方法:
 在Android SDK Manager 下载 Extra里Android Support 到最新
 成功后能找到下面的目录
 C:\Users\ivan\AppData\Local\Android\sdk\extras\android\m2repository\com\android\support\support-v4\23.2.1 

 报错:react native Unable to install app-debug.apk
 解决方法:
 更改 AwesomeProject\android\build.gradlel里的版本为1.2.3
 */

 方式一: 手机直接连笔记本电脑wifi
 Android手机wifi联通电脑 /*
 电脑 cmd 进入命令端
 > netsh wlan set hostednetwork mode=allow ssid=glm key=00000000
 > netsh wlan start hostednetwork 
 手机 wifi链接name 密码 00000000
 */ 


 更改 AwesomeProject/index.android.js里的内容
 react-native run-android //运行,会看到手机显示内容有变化,表示环境ok 

 方式二:通过无线路由连接电脑
 摇动手机 //会看到弹出的提示列表
 选择Dev Setttings 
 选择Debug server host & port for device //设置IP地址如 192.168.1.5:8081 (需和电脑网卡ip一致,且手机和电脑在同一局域网)
 回到Welcome界面

} 

{//------------------------------------Webstorm------------------------- 源码编辑软件IDE(替代 Nuclide (React Native 默认IDE),因它不支持window)
 安装版本 WebStorm-2016.3.2.exe
 破解码activation code://43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QTczWVlKIiwibGljZW5zZWVOYW1lIjoibGFuIHl1IiwiYXNzaWduZWVOYW1lIjoiIiwiYXNzaWduZWVFbWFpbCI6IiIsImxpY2Vuc2VSZXN0cmljdGlvbiI6IkZvciBlZHVjYXRpb25hbCB1c2Ugb25seSIsImNoZWNrQ29uY3VycmVudFVzZSI6ZmFsc2UsInByb2R1Y3RzIjpbeyJjb2RlIjoiSUkiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJBQyIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IkRQTiIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlBTIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiRE0iLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJDTCIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlJTMCIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IlJDIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiUEMiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJSTSIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9LHsiY29kZSI6IldTIiwicGFpZFVwVG8iOiIyMDE3LTAyLTI1In0seyJjb2RlIjoiREIiLCJwYWlkVXBUbyI6IjIwMTctMDItMjUifSx7ImNvZGUiOiJEQyIsInBhaWRVcFRvIjoiMjAxNy0wMi0yNSJ9XSwiaGFzaCI6IjMzOTgyOTkvMCIsImdyYWNlUGVyaW9kRGF5cyI6MCwiYXV0b1Byb2xvbmdhdGVkIjpmYWxzZSwiaXNBdXRvUHJvbG9uZ2F0ZWQiOmZhbHNlfQ==-keaxIkRgXPKE4BR/ZTs7s7UkP92LBxRe57HvWamu1EHVXTcV1B4f/KNQIrpOpN6dgpjig5eMVMPmo7yMPl+bmwQ8pTZaCGFuLqCHD1ngo6ywHKIQy0nR249sAUVaCl2wGJwaO4JeOh1opUx8chzSBVRZBMz0/MGyygi7duYAff9JQqfH3p/BhDTNM8eKl6z5tnneZ8ZG5bG1XvqFTqWk4FhGsEWdK7B+He44hPjBxKQl2gmZAodb6g9YxfTHhVRKQY5hQ7KPXNvh3ikerHkoaL5apgsVBZJOTDE2KdYTnGLmqxghFx6L0ofqKI6hMr48ergMyflDk6wLNGWJvYHLWw==-MIIEPjCCAiagAwIBAgIBBTANBgkqhkiG9w0BAQsFADAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBMB4XDTE1MTEwMjA4MjE0OFoXDTE4MTEwMTA4MjE0OFowETEPMA0GA1UEAwwGcHJvZDN5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxcQkq+zdxlR2mmRYBPzGbUNdMN6OaXiXzxIWtMEkrJMO/5oUfQJbLLuMSMK0QHFmaI37WShyxZcfRCidwXjot4zmNBKnlyHodDij/78TmVqFl8nOeD5+07B8VEaIu7c3E1N+e1doC6wht4I4+IEmtsPAdoaj5WCQVQbrI8KeT8M9VcBIWX7fD0fhexfg3ZRt0xqwMcXGNp3DdJHiO0rCdU+Itv7EmtnSVq9jBG1usMSFvMowR25mju2JcPFp1+I4ZI+FqgR8gyG8oiNDyNEoAbsR3lOpI7grUYSvkB/xVy/VoklPCK2h0f0GJxFjnye8NT1PAywoyl7RmiAVRE/EKwIDAQABo4GZMIGWMAkGA1UdEwQCMAAwHQYDVR0OBBYEFGEpG9oZGcfLMGNBkY7SgHiMGgTcMEgGA1UdIwRBMD+AFKOetkhnQhI2Qb1t4Lm0oFKLl/GzoRykGjAYMRYwFAYDVQQDDA1KZXRQcm9maWxlIENBggkA0myxg7KDeeEwEwYDVR0lBAwwCgYIKwYBBQUHAwEwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQC9WZuYgQedSuOc5TOUSrRigMw4/+wuC5EtZBfvdl4HT/8vzMW/oUlIP4YCvA0XKyBaCJ2iX+ZCDKoPfiYXiaSiH+HxAPV6J79vvouxKrWg2XV6ShFtPLP+0gPdGq3x9R3+kJbmAm8w+FOdlWqAfJrLvpzMGNeDU14YGXiZ9bVzmIQbwrBA+c/F4tlK/DV07dsNExihqFoibnqDiVNTGombaU2dDup2gwKdL81ua8EIcGNExHe82kjF4zwfadHk3bQVvbfdAwxcDy4xBjs3L4raPLU3yenSzr/OEur1+jfOxnQSmEcMXKXgrAQ9U55gwjcOFKrgOxEdek/Sk1VfOjvS+nuM4eyEruFMfaZHzoQiuw4IqgGc45ohFH0UUyjYcuFxxDSU9lMCv8qdHKm+wnPRb0l9l5vXsCBDuhAGYD6ss+Ga+aDY6f/qXZuUCEUOH3QUNbbCUlviSz6+GiRnt1kA9N2Qachl+2yBfaqUqr8h7Z2gsx5LcIf5kYNsqJ0GavXTVyWh7PYiKX4bs354ZQLUwwa/cG++2+wNWP+HtBhVxMRNTdVhSm38AknZlD+PTAsWGu9GyLmhti2EnVwGybSD2Dxmhxk3IPCkhKAK+pl0eWYGZWG3tJ9mZ7SowcXLWDFAk0lRJnKGFMTggrWjV8GYpw5bq23VmIqqDLgkNzuoog==
 File --> Open //导入项目源码(如AwesomeProject 源码)
 Setting-->Javascript-->选 React JSX 
 Setting-->Javascript-->Library --> Download 选 react 和react-native下载 
}} 
{//=======================================入门==============================
http://reactnative.cn/docs/0.41/getting-started.html
{//最简示例 helloworld 
 > cd AwesomeProject 

 {//index.android.js 更改为下面内容
 import React, { Component } from 'react'; //从模块 'react'中导入 对象( React Component) 
 import { AppRegistry, Text } from 'react-native'; class HelloWorldApp extends Component {//定义继承于Component的类 HelloWorldApp
 render() {//渲染到真实的DOM上
 return (
 <Text>Hello world!</Text> //jsx语法(js中嵌入html标签)
 );
 }
 } //注册HelloWorldApp为项目AwesomeProject的根组件(注意'AwesomeProject'必须和你init创建的项目名一致)
 AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp); 
 }

 > react-native run-android {//JSX(js+xml -- js中嵌入html) --> 避免js html的割裂(频繁查找dom元素),实现真正的组件化 
 {//定制组件 Component
 }

 {//区分 html标签和自定义组件 -- 大小写
 //---html标签 小写 (注: react native 里不支持 h5 html标签,它里面全是对原生手机系统的api封装)
 <h1>entry</h1>
 <div class="footer"> Copyright 2015.12.10. </div> 
 <input type="button" value="hello" οnclick="msg()" /> 
 //---自定义组件 大写
 <Text>Hello world!</Text>
 } 
 } 

} 

{//定制组件属性props(静态: 一经指定,不再更改)

 {//设置图片来源和宽高
 //---index.android.js
 import React, { Component } from 'react'; //从模块 'react'中导入 对象( React Component)
 import { AppRegistry, Image } from 'react-native'; //从模块 'react-native'中导入Image对象 class HelloWorldApp extends Component {//定义继承于Component的类 HelloWorldApp
 render() {//渲染到真实的DOM上
 return ( <Image
 source={require('./img/menu_home.png')} //设置图片来源属性source,{} 是jsx语法(html标签里嵌入js)
 style={{width:32,height:32}} //设置图片风格属性(图片的宽高),里面的{}表示是json对象
 />
 );
 }
 }
 //注册HelloWorldApp为项目AwesomeProject的根组件(注意'AwesomeProject'必须和你init创建的项目名一致)
 AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
 }

 {//设置组件名字属性
 //---index.android.js
 import React, { Component } from 'react';
 import { AppRegistry,View } from 'react-native'; var MyComponent = require('./MyComponent'); //导入当前目录下的MyComponent组件模块
 class HelloWorldApp extends Component {
 render() {
 return (
 <View style={{alignItems: 'center'}}> /* 设置显示布局View 为居中对齐显示*/
 <MyComponent name='yzg' /> /* 定制组件的属性 name*/
 <MyComponent name='ivan' />
 </View>
 );
 }
 } AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
 //---MyComponent.js
 import React, { Component } from 'react';
 import { Text } from 'react-native'; class MyComponent extends Component {
 render() {
 return (
 <Text>Hello1 {this.props.name}!</Text> /*使用组件本身的属性name*/
 );
 }
 } module.exports = MyComponent; //导出组件模块
 }

 {//设置组件style样式属性
 //---index.android.js
 import React, { Component } from 'react';
 import { AppRegistry } from 'react-native'; var MyComponent = require('./MyComponent'); //导入当前目录下的MyComponent组件模块
 class HelloWorldApp extends Component {
 render() {
 return (
 <MyComponent name='yzg' /> /* 定制组件的属性 name*/
 );
 }
 } AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
 //---MyComponent.js
 import React, { Component } from 'react';
 import { Text,StyleSheet } from 'react-native'; class MyComponent extends Component {
 render() {
 return (
 <Text style={styles.bigblue}>Hello1 {this.props.name}!</Text> 
 );
 }
 } const styles = StyleSheet.create({ //样式集中设置(详见组件API 如Text组件里style属性)
 bigblue: {
 color: 'blue',
 fontWeight: 'bold',
 fontSize: 30,
 },
 red: {
 color: 'red',
 },
 }); module.exports = MyComponent; //导出组件模块
 }

} 

{//定制组件状态state(动态)
 {//定时闪烁
 //---index.android.js
 import React, { Component } from 'react';
 import { AppRegistry } from 'react-native'; var MyComponent = require('./MyComponent'); //导入当前目录下的MyComponent组件模块
 class HelloWorldApp extends Component {
 render() {
 return (
 <MyComponent name='yzg' /> /* 定制组件的属性 name*/
 );
 }
 } AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
 //---MyComponent.js
 import React, { Component } from 'react';
 import { Text } from 'react-native'; class MyComponent extends Component {
 constructor(props) {//初始化组件(逐渐替换淘汰es5的getInitialState)
 super(props); //继承父属性
 this.state = { showText: true }; // 每1000毫秒对showText状态做一次取反操作
 setInterval(() => {
 this.setState({ showText: !this.state.showText }); //动态更改状态state
 }, 1000);
 } render() {
 // 根据当前showText的值决定是否显示text内容
 let display = this.state.showText ? this.props.name : ' ';
 return (
 <Text>{display}</Text>
 );
 }
 } module.exports = MyComponent; //导出组件模块 

 } 
} {//组合多个组件
 {//用View组合多个组件
 import React, { Component } from 'react';
 import { Text,View,Image } from 'react-native'; //注:render渲染时,只能return一个element,多个时加View,否则会报错JSX elements must be wrapped in an enclosing tag
 class MyComponent extends Component {
 render() {
 return (//return 多个组件时需用View包裹起来
 <View >
 <Text>Hello</Text>
 <Image
 source={require('./img/menu_home.png')} //设置图片来源属性source,{} 是jsx语法(html标签里嵌入js)
 style={{width:32,height:32}} //设置图片风格属性(图片的宽高),里面的{}表示是json对象
 />
 </View>
 );
 }
 } module.exports = MyComponent; //导出组件模块
 }

 {//安排组件位置(弹性布局Flex)
 import React, { Component } from 'react';
 import { Text,View,Image } from 'react-native'; //注:render渲染时,只能return一个element,多个时加View,否则会报错JSX elements must be wrapped in an enclosing tag
 class MyComponent extends Component {
 render() {
 return (//return 多个组件时需用View包裹起来
 <View style={{
 flex: 2,
 flexDirection: 'row', //设置布局的主轴(默认为column 列)为行row
 justifyContent: 'center', //子元素沿着主轴的排列方式flex-start、center、flex-end、space-around以及space-between
 alignItems: 'flex-end', //次轴(与主轴垂直)排列 flex-start、center、flex-end以及stretch(伸缩要生效,子元素不能有固定尺寸)
 }} >
 <Text>Hello</Text>
 <Image
 source={require('./img/menu_home.png')} //设置图片来源属性source,{} 是jsx语法(html标签里嵌入js)
 />
 </View>
 );
 }
 } module.exports = MyComponent; //导出组件模块 

 } 

 {//列表滚动显示ListView
 {//最简ListView
 //注:一般不用ScrollView(性能较差)
 import React, { Component } from 'react';
 import {Text,ListView } from 'react-native';
 //注:render渲染时,只能return一个element,多个时加View,否则会报错JSX elements must be wrapped in an enclosing tag
 class MyComponent extends Component {
 constructor(props) {
 super(props);
 //ListView 会根据rowHasChanged算法去检查数据更新,决定哪些行需要重新渲染
 const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
 this.state = {
 dataSource: ds.cloneWithRows([
 'yzg', 'ivan',1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30
 ])
 };
 }
 render() {
 return (
 <ListView
 dataSource={this.state.dataSource} //列表的数据源
 renderRow={(rowData) => <Text>{rowData}</Text>} //逐个解析数据源渲染显示(渲染谁由rowHasChanged决定)
 />
 );
 }
 } module.exports = MyComponent; //导出组件模块 
 }

 {//---index.android.js
 import React, { Component } from 'react';
 import { AppRegistry } from 'react-native'; var StoryList = require('./StoryList'); //导入当前目录下的MyComponent组件模块
 class HelloWorldApp extends Component {
 render() {
 return (
 <StoryList />
 );
 }
 } AppRegistry.registerComponent('AwesomeProject', () => HelloWorldApp);
 }

 {//---StoryList.js
 import React, { Component } from 'react';
 import {Text,ListView } from 'react-native'; var StoryItem = require('./StoryItem'); //导入当前目录下的MyComponent组件模块
 //注:render渲染时,只能return一个element,多个时加View,否则会报错JSX elements must be wrapped in an enclosing tag
 class StoryList extends Component {
 constructor(props) {
 super(props);
 //ListView 会根据rowHasChanged算法去检查数据更新,决定哪些行需要重新渲染
 const ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2});
 this.state = {
 dataSource: ds.cloneWithRows([//设置列表的数据源
 {name:'yzg',pic:require('./img/menu_home.png')},
 {name:'ivan',pic:require('./img/ic_back_white.png')},
 {name:'lili',pic:require('./img/ic_collect_white.png')},
 {name:'wang',pic:require('./img/ic_collected_white.png')},
 ])
 };
 }
 render() {
 return (
 <ListView
 dataSource={this.state.dataSource} //列表的数据源
 renderRow={(rowData) => <StoryItem obj={rowData} />} //逐个解析数据源渲染显示(渲染谁由rowHasChanged决定)
 />
 );
 }
 } module.exports = StoryList; //导出组件模块 
 }

 {//---StoryItem.js
 import React, { Component } from 'react';
 import { Text,View,Image } from 'react-native'; //注:render渲染时,只能return一个element,多个时加View,否则会报错JSX elements must be wrapped in an enclosing tag
 class StoryItem extends Component {
 render() {
 return (//return 多个组件时需用View包裹起来
 <View >
 <Text>{this.props.obj.name} </Text>
 <Image
 source={this.props.obj.pic} //设置图片来源属性source,{} 是jsx语法(html标签里嵌入js)
 />
 </View>
 );
 }
 } module.exports = StoryItem; //导出组件模块
 }
 }

} }
}