├── .idea ├── misc.xml ├── modules.xml ├── react-native-learn.iml └── workspace.xml ├── Example ├── .babelrc ├── .buckconfig ├── .flowconfig ├── .gitignore ├── .watchmanconfig ├── App │ ├── Base │ │ ├── App.js │ │ ├── Component │ │ │ ├── Util.js │ │ │ ├── leftNavBtn.js │ │ │ └── test.js │ │ ├── Demo.json │ │ └── Root.js │ ├── Page │ │ ├── FivePage │ │ │ ├── Component │ │ │ │ ├── Actions │ │ │ │ │ ├── ActionTypes.js │ │ │ │ │ ├── HomeAction.js │ │ │ │ │ └── Index.js │ │ │ │ ├── Base │ │ │ │ │ ├── Root.js │ │ │ │ │ └── TabBarView.js │ │ │ │ ├── Common │ │ │ │ │ ├── Config.js │ │ │ │ │ ├── ConnectComponent.js │ │ │ │ │ ├── HomeContainer.js │ │ │ │ │ ├── Loading.js │ │ │ │ │ └── Request.js │ │ │ │ ├── Pages │ │ │ │ │ ├── Main │ │ │ │ │ │ ├── Main.js │ │ │ │ │ │ ├── components │ │ │ │ │ │ │ ├── ActionButton.js │ │ │ │ │ │ │ ├── ListItem.js │ │ │ │ │ │ │ └── StatusBar.js │ │ │ │ │ │ └── styles.js │ │ │ │ │ └── News │ │ │ │ │ │ ├── News.js │ │ │ │ │ │ ├── NewsDetail.js │ │ │ │ │ │ ├── NewsItem.js │ │ │ │ │ │ └── NewsList.js │ │ │ │ ├── Reducers │ │ │ │ │ ├── HomeReducer.js │ │ │ │ │ └── RootReducer.js │ │ │ │ ├── Resource │ │ │ │ │ ├── main-normal.png │ │ │ │ │ ├── main-selected.png │ │ │ │ │ ├── news-normal.png │ │ │ │ │ └── news-selected.png │ │ │ │ └── Store │ │ │ │ │ └── Store.js │ │ │ └── Five.js │ │ ├── FourPage │ │ │ └── Four.js │ │ ├── OnePage │ │ │ └── One.js │ │ ├── SixPage │ │ │ ├── Six.js │ │ │ ├── actions │ │ │ │ ├── actionTypes.js │ │ │ │ └── homeAction.js │ │ │ ├── base │ │ │ │ ├── root.js │ │ │ │ └── tabBarView.js │ │ │ ├── common │ │ │ │ ├── HeaderView.js │ │ │ │ ├── LoadMoreFooter.js │ │ │ │ ├── Loading.js │ │ │ │ ├── common.js │ │ │ │ └── utils.js │ │ │ ├── containers │ │ │ │ ├── detail.js │ │ │ │ ├── homeContainer.js │ │ │ │ ├── mainContainer.js │ │ │ │ └── 信息页_选择_icon.png │ │ │ ├── pages │ │ │ │ ├── Home.js │ │ │ │ └── HomeDetial.js │ │ │ ├── reducers │ │ │ │ ├── homeReducer.js │ │ │ │ └── rootReducer.js │ │ │ ├── resource │ │ │ │ ├── main-normal.png │ │ │ │ ├── main-selected.png │ │ │ │ ├── news-normal.png │ │ │ │ └── news-selected.png │ │ │ └── store │ │ │ │ └── store.js │ │ ├── ThreePage │ │ │ ├── PushButton.js │ │ │ └── Three.js │ │ └── TwoPage │ │ │ ├── Component │ │ │ ├── Account │ │ │ │ ├── Account.js │ │ │ │ └── Login.js │ │ │ ├── Common │ │ │ │ ├── config.js │ │ │ │ └── request.js │ │ │ ├── Edit │ │ │ │ └── Edit.js │ │ │ ├── List │ │ │ │ ├── Detail.js │ │ │ │ ├── List.js │ │ │ │ ├── VideoPlayerAndroid.js │ │ │ │ ├── VideoPlayeriOS.js │ │ │ │ └── item.js │ │ │ └── Picture │ │ │ │ └── Picture.js │ │ │ ├── RTTabBar.js │ │ │ └── Two.js │ └── Root.js ├── __tests__ │ ├── index.android.js │ └── index.ios.js ├── android │ ├── app │ │ ├── BUCK │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src │ │ │ └── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── assets │ │ │ └── fonts │ │ │ │ ├── Entypo.ttf │ │ │ │ ├── EvilIcons.ttf │ │ │ │ ├── FontAwesome.ttf │ │ │ │ ├── Foundation.ttf │ │ │ │ ├── Ionicons.ttf │ │ │ │ ├── MaterialIcons.ttf │ │ │ │ ├── Octicons.ttf │ │ │ │ └── Zocial.ttf │ │ │ ├── java │ │ │ └── com │ │ │ │ └── example │ │ │ │ ├── MainActivity.java │ │ │ │ └── MainApplication.java │ │ │ └── res │ │ │ ├── mipmap-hdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ └── ic_launcher.png │ │ │ └── values │ │ │ ├── strings.xml │ │ │ └── styles.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ ├── gradle-wrapper.jar │ │ │ └── gradle-wrapper.properties │ ├── gradlew │ ├── gradlew.bat │ ├── keystores │ │ ├── BUCK │ │ └── debug.keystore.properties │ └── settings.gradle ├── index.android.js ├── index.ios.js ├── ios │ ├── Example.xcodeproj │ │ ├── project.pbxproj │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Example.xcscheme │ ├── Example │ │ ├── Base.lproj │ │ │ └── LaunchScreen.xib │ │ ├── Controller │ │ │ ├── PushController.h │ │ │ ├── PushController.m │ │ │ ├── TestController.h │ │ │ └── TestController.m │ │ ├── Images.xcassets │ │ │ ├── AppIcon.appiconset │ │ │ │ └── Contents.json │ │ │ ├── Contents.json │ │ │ ├── 周期.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── 周期.png │ │ │ ├── 宝宝.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── 宝宝.png │ │ │ ├── 新闻.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── 新闻.png │ │ │ ├── 跳转.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── 跳转.png │ │ │ └── 闹钟.imageset │ │ │ │ ├── Contents.json │ │ │ │ └── 闹钟.png │ │ ├── Info.plist │ │ ├── Main │ │ │ ├── AppDelegate.h │ │ │ └── AppDelegate.m │ │ ├── Project │ │ │ ├── RN组件 │ │ │ │ ├── ReactView.h │ │ │ │ └── ReactView.m │ │ │ ├── RN需要组件 │ │ │ │ ├── PushNative.h │ │ │ │ ├── PushNative.m │ │ │ │ ├── RCTPushViewManager.h │ │ │ │ └── RCTPushViewManager.m │ │ │ └── 原生组件 │ │ │ │ ├── PushButton.h │ │ │ │ └── PushButton.m │ │ └── main.m │ └── ExampleTests │ │ ├── ExampleTests.m │ │ └── Info.plist └── package.json └── README.md /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | Assignment issuesJavaScript 12 | 13 | 14 | CSS 15 | 16 | 17 | CoffeeScript 18 | 19 | 20 | General 21 | 22 | 23 | GeneralCoffeeScript 24 | 25 | 26 | GeneralJavaScript 27 | 28 | 29 | JavaScript 30 | 31 | 32 | Potentially confusing code constructsJavaScript 33 | 34 | 35 | Probable bugsCSS 36 | 37 | 38 | 39 | 40 | AngularJS 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | $USER_HOME$/.subversion 64 | 65 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/react-native-learn.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/workspace.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 39 | 40 | 1476863602690 41 | 45 | 46 | 47 | 48 | 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /Example/.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["react-native"] 3 | } -------------------------------------------------------------------------------- /Example/.buckconfig: -------------------------------------------------------------------------------- 1 | 2 | [android] 3 | target = Google Inc.:Google APIs:23 4 | 5 | [maven_repositories] 6 | central = https://repo1.maven.org/maven2 7 | -------------------------------------------------------------------------------- /Example/.flowconfig: -------------------------------------------------------------------------------- 1 | [ignore] 2 | 3 | # We fork some components by platform. 4 | .*/*[.]android.js 5 | 6 | # Ignore templates with `@flow` in header 7 | .*/local-cli/generator.* 8 | 9 | # Ignore malformed json 10 | .*/node_modules/y18n/test/.*\.json 11 | 12 | # Ignore the website subdir 13 | /website/.* 14 | 15 | # Ignore BUCK generated dirs 16 | /\.buckd/ 17 | 18 | # Ignore unexpected extra @providesModule 19 | .*/node_modules/commoner/test/source/widget/share.js 20 | 21 | # Ignore duplicate module providers 22 | # For RN Apps installed via npm, "Libraries" folder is inside node_modules/react-native but in the source repo it is in the root 23 | .*/Libraries/react-native/React.js 24 | .*/Libraries/react-native/ReactNative.js 25 | .*/node_modules/jest-runtime/build/__tests__/.* 26 | 27 | [include] 28 | 29 | [libs] 30 | node_modules/react-native/Libraries/react-native/react-native-interface.js 31 | node_modules/react-native/flow 32 | flow/ 33 | 34 | [options] 35 | module.system=haste 36 | 37 | esproposal.class_static_fields=enable 38 | esproposal.class_instance_fields=enable 39 | 40 | experimental.strict_type_args=true 41 | 42 | munge_underscores=true 43 | 44 | module.name_mapper='^image![a-zA-Z0-9$_-]+$' -> 'GlobalImageStub' 45 | module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub' 46 | 47 | suppress_type=$FlowIssue 48 | suppress_type=$FlowFixMe 49 | suppress_type=$FixMe 50 | 51 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(>=0\\.\\(3[0-2]\\|[1-2][0-9]\\|[0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\) 52 | suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(>=0\\.\\(3[0-2]\\|1[0-9]\\|[1-2][0-9]\\).[0-9]\\)? *\\(site=[a-z,_]*react_native[a-z,_]*\\)?)\\)?:? #[0-9]+ 53 | suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy 54 | 55 | unsafe.enable_getters_and_setters=true 56 | 57 | [version] 58 | ^0.32.0 59 | -------------------------------------------------------------------------------- /Example/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | 25 | # Android/IJ 26 | # 27 | *.iml 28 | .idea 29 | .gradle 30 | local.properties 31 | 32 | # node.js 33 | # 34 | node_modules/ 35 | npm-debug.log 36 | 37 | # BUCK 38 | buck-out/ 39 | \.buckd/ 40 | android/app/libs 41 | android/keystores/debug.keystore 42 | -------------------------------------------------------------------------------- /Example/.watchmanconfig: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /Example/App/Base/App.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/7. 3 | */ 4 | import React from 'react'; 5 | import { 6 | AppRegistry, 7 | Navigator, 8 | View, 9 | StyleSheet, 10 | Text, 11 | Image, 12 | } from 'react-native'; 13 | 14 | html:5 15 | 16 | import Root from '../Base/Root'; 17 | 18 | export default class App extends React.Component { 19 | render(){ 20 | return( 21 | 22 | { 26 | if (route.sceneConfig) { 27 | return route.sceneConfig; 28 | } 29 | return Navigator.SceneConfigs.PushFromRight; 30 | } } 31 | renderScene={(route, navigator) => { 32 | let Component = route.component; 33 | return ( 34 | 36 | ) 37 | } 38 | } 39 | /> 40 | 41 | ) 42 | } 43 | } -------------------------------------------------------------------------------- /Example/App/Base/Component/Util.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/10. 3 | */ 4 | import React from 'react'; 5 | import { PixelRatio } from 'react-native'; 6 | import Dimensions from 'Dimensions'; 7 | 8 | const Util = { 9 | ratio: PixelRatio.get(), 10 | pixel: 1 / PixelRatio.get(), 11 | size: { 12 | width: Dimensions.get('window').width, 13 | height: Dimensions.get('window').height 14 | }, 15 | post(url, data, callback) { 16 | const fetchOptions = { 17 | method: 'POST', 18 | headers: { 19 | 'Accept': 'application/json', 20 | 'Content-Type': 'application/json' 21 | }, 22 | body: JSON.stringify(data) 23 | }; 24 | 25 | fetch(url, fetchOptions) 26 | .then((response) => { 27 | return response.json() 28 | }) 29 | .then((responseData) => { 30 | callback(responseData); 31 | }); 32 | }, 33 | }; 34 | export default Util; -------------------------------------------------------------------------------- /Example/App/Base/Component/leftNavBtn.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/11. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | TouchableOpacity, 11 | Image 12 | } from 'react-native'; 13 | 14 | import icon from './test'; 15 | // var Icon = require('react-native-vector-icons/FontAwesome'); 16 | 17 | var Icon = require('react-native-vector-icons/Ionicons'); 18 | 19 | export default class leftNavBtn extends Component { 20 | static defaultProps = { 21 | // 回调函数 22 | popToHome: null 23 | }; 24 | 25 | render() { 26 | const charmander = 'http://oyster.ignimgs.com/mediawiki/apis.ign.com/pokemon-blue-version/d/d4/Charmander.gif'; 27 | return ( 28 | 29 | 35 | {/**/} 36 | {/*{icon('arrow-back')}*/} 37 | {/**/} 38 | 39 | 40 | ); 41 | } 42 | popTopHome(){ 43 | this.props.popToHome(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/App/Base/Component/test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/11. 3 | */ 4 | 5 | import React, { Component } from 'react'; 6 | import { 7 | AppRegistry, 8 | StyleSheet, 9 | Text, 10 | View 11 | } from 'react-native'; 12 | class TestDemo extends Component { 13 | render() { 14 | 15 | 16 | var map = { 17 | "arrow": "62976", 18 | "checked": "62977", 19 | "checked-s": "62978", 20 | "tag-svip": "62995" 21 | }; 22 | } 23 | } 24 | var map = {"arrow":"58885","checked":"58885","checked-s":"62978","tag-svip":"62995"}; 25 | 26 | module.exports = (name)=>String.fromCharCode(map[name]); 27 | module.exports.map = map; -------------------------------------------------------------------------------- /Example/App/Base/Demo.json: -------------------------------------------------------------------------------- 1 | { 2 | "days": [{ 3 | "key": "1", 4 | "title": "计时器", 5 | "icon": "闹钟", 6 | "component": "Time" 7 | },{ 8 | "key" : "2", 9 | "title" : "购物", 10 | "icon": "闹钟", 11 | "component": "Time" 12 | }], 13 | "exclude": "node_modules" 14 | } -------------------------------------------------------------------------------- /Example/App/Base/Root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/7. 3 | */ 4 | import React from 'react'; 5 | import { 6 | AppRegistry, 7 | View, 8 | StyleSheet, 9 | Text, 10 | Platform, 11 | Image, 12 | ListView, 13 | TouchableOpacity, 14 | InteractionManager, 15 | NativeModules, 16 | requireNativeComponent 17 | } from 'react-native'; 18 | 19 | var Dimensions = require('Dimensions'); 20 | var {width} = Dimensions.get('window'); 21 | 22 | import NavBar from 'react-native-navbar'; 23 | import Time from '../Page/OnePage/One'; 24 | import Baby from '../Page/TwoPage/Two'; 25 | import Cycle from '../Page/FourPage/Four'; 26 | import News from '../Page/FivePage/Five'; 27 | import Redux from '../Page/SixPage/Six'; 28 | 29 | 30 | 31 | var Push = NativeModules.PushNative; 32 | 33 | // var ShareBt = requireNativeComponent('PushButton', PushButton); 34 | 35 | import PushButton from '../Page/ThreePage/PushButton'; 36 | 37 | 38 | export default class Root extends React.Component { 39 | 40 | componentDidMount() { 41 | this.loadJsonData(); 42 | } 43 | 44 | loadJsonData(){ 45 | this.setState({ 46 | // cell的数据源 47 | dataSource: this.state.dataSource.cloneWithRows(this.state.days), 48 | }); 49 | 50 | } 51 | 52 | constructor(props){ 53 | super(props); 54 | const dataSource = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2}); 55 | this.state = { 56 | dataSource: dataSource, 57 | days: [{ 58 | key: 1, 59 | title: "计时器", 60 | icon: "闹钟", 61 | component: Time 62 | },{ 63 | key : 2, 64 | title : "宝宝秀", 65 | icon: "宝宝", 66 | component: Baby 67 | },{ 68 | key : 3, 69 | title : "跳转", 70 | icon: "跳转", 71 | component: Push 72 | },{ 73 | key : 4, 74 | title : "周期", 75 | icon: "周期", 76 | component:Cycle 77 | },{ 78 | key : 5, 79 | title : "百思不得姐", 80 | icon: "新闻", 81 | component:News 82 | },{ 83 | key : 6, 84 | title : "Redux", 85 | icon: "Redux", 86 | component:Redux 87 | }, 88 | 89 | ], 90 | exclude: "node_modules" 91 | } 92 | 93 | this.renderRow = this.renderRow.bind(this); 94 | 95 | } 96 | 97 | 98 | render() { 99 | var titleConfig = { 100 | title: 'Hello World!', 101 | style: {color:'black',fontSize:20,fontWeight:'600'} 102 | }; 103 | return ( 104 | 105 | {/*导航条*/} 106 | 110 | 111 | 112 | 117 | 118 | ) 119 | } 120 | 121 | renderRow(rowData,rowID,sectionID){ 122 | //利用map做了遍历布局,可以在以后使用 123 | // var onThis = this; 124 | // var days = DemoJson.days.map(function(elem, index){ 125 | // return( 126 | // onThis.jumpToDay(index)}> 127 | // 128 | // {rowData.title} 129 | // 130 | // ); 131 | // }); 132 | // return( 133 | // {days} 134 | // ) 135 | 136 | return( 137 | 138 | this.jumpToDay(sectionID)}> 140 | 141 | {rowData.title} 142 | 143 | 144 | ); 145 | } 146 | 147 | jumpToDay(index){ 148 | if(index == 2){ 149 | console.log(index); 150 | Push.RNOpenOneVC('测试'); 151 | }else { 152 | var days = this.state.days[index]; 153 | let {navigator} = this.props; 154 | if (navigator) { 155 | InteractionManager.runAfterInteractions(()=> { 156 | navigator.push({ 157 | title: days.title, 158 | index: index + 1, 159 | component: days.component 160 | }) 161 | }); 162 | } 163 | } 164 | } 165 | 166 | } 167 | 168 | const styles = StyleSheet.create({ 169 | contentViewStyle: { 170 | // 多个cell再同一行显示 171 | flexWrap: 'wrap', 172 | // 设置主轴方向 173 | flexDirection: 'row', 174 | alignItems: 'center', 175 | width: width 176 | }, 177 | }); 178 | 179 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Actions/ActionTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | //主页actions 5 | export const FETCH_HOME_LIST = 'FETCH_HOME_LIST'; 6 | export const RECEIVE_HOME_LIST = 'RECEIVE_HOME_LIST'; 7 | export const RESET_STATE = 'RESET_STATE'; -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Actions/HomeAction.js: -------------------------------------------------------------------------------- 1 | import * as types from './ActionTypes'; 2 | import Request from '../Common/Request'; 3 | import Config from '../Common/Config'; 4 | 5 | let cacheResults = { 6 | items:[], 7 | allPage:0, 8 | currentPage:0 9 | }; 10 | 11 | let id = ''; 12 | 13 | export let Home = (page,type ,isLoadMore,isRefreshing,isLoading,blackArr) => { 14 | // let url = Config.api.homeList + '&page=' + page + '&type=' + id; 15 | let url = Config.api.homeList; 16 | 17 | // id = type; 18 | 19 | // console.log(id); 20 | // console.log(type); 21 | return dispatch => { 22 | dispatch(fetchHomeList(isLoading,isRefreshing,isLoadMore)); 23 | return Request.get(url,{ 24 | type:type, 25 | page:page, 26 | }, (response) => { 27 | // console.log(response.showapi_res_body.pagebean); 28 | 29 | blackArr(response.showapi_res_body.pagebean); 30 | 31 | }, (error) => { 32 | console.log(error); 33 | dispatch(receiveHomeList([])); 34 | }); 35 | } 36 | }; 37 | 38 | let fetchHomeList = (isLoadMore, isRefreshing, isLoading) => { 39 | return { 40 | type: types.FETCH_HOME_LIST, 41 | isLoadMore: isLoadMore, 42 | isRefreshing: isRefreshing, 43 | isLoading: isLoading, 44 | } 45 | }; 46 | 47 | let receiveHomeList = (homeList) => { 48 | console.log(homeList.length); 49 | return { 50 | type: types.RECEIVE_HOME_LIST, 51 | homeList: homeList, 52 | } 53 | }; 54 | 55 | let resetHomeList = (homeList) => { 56 | return{ 57 | type: types.RESET_STATE, 58 | homeList:homeList, 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Actions/Index.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | import * as home from './HomeAction'; 5 | export default { 6 | ...home, 7 | 8 | } 9 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Base/Root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | Navigator 14 | } from 'react-native'; 15 | 16 | import TabBarView from './TabBarView'; 17 | 18 | export default class Root extends Component { 19 | render() { 20 | return ( 21 | 22 | { 26 | if (route.sceneConfig) { 27 | return route.sceneConfig; 28 | } 29 | return Navigator.SceneConfigs.PushFromRight; 30 | } } 31 | renderScene={(route, navigator) => { 32 | let Component = route.component; 33 | return ( 34 | 35 | ) 36 | } } 37 | /> 38 | 39 | ); 40 | } 41 | } 42 | 43 | 44 | const styles = StyleSheet.create({ 45 | container: { 46 | flex: 1, 47 | justifyContent: 'center', 48 | alignItems: 'center', 49 | backgroundColor: '#F5FCFF', 50 | }, 51 | welcome: { 52 | fontSize: 20, 53 | textAlign: 'center', 54 | margin: 10, 55 | }, 56 | instructions: { 57 | textAlign: 'center', 58 | color: '#333333', 59 | marginBottom: 5, 60 | }, 61 | }); 62 | 63 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Base/TabBarView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 16/9/10. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | View, 7 | Text, 8 | Image, 9 | } from 'react-native'; 10 | 11 | import TabNavigator from 'react-native-tab-navigator'; 12 | 13 | import Icon from 'react-native-vector-icons/Ionicons'; 14 | 15 | import Home from '../Pages/News/News'; 16 | import Main from '../Pages/Main/Main'; 17 | import ConnectComponent from '../Common/ConnectComponent'; 18 | 19 | // const HomeUI=ConnectComponent(Home); 20 | 21 | import HomeContainer from '../Common/HomeContainer'; 22 | 23 | 24 | const tabBarItems = [ 25 | { title: '新闻', icon: () => , 26 | selectedIcon: () => 27 | ,component: HomeContainer }, 28 | { title: '我的', icon: () => , 29 | selectedIcon: () => , 30 | component: Main }, 31 | // { title: '关于', icon: () => , Component: HomeContainer }, 32 | ] 33 | 34 | export default class TabBarView extends Component { 35 | constructor(props) { 36 | super(props); 37 | this.state = { 38 | selectedTab: tabBarItems[0].title, 39 | }; 40 | } 41 | render(){ 42 | return( 43 | 44 | { 45 | tabBarItems.map((controller,i) => { 46 | let Component = controller.component; 47 | return( 48 | this.setState({selectedTab:controller.title})} 55 | titleStyle={{color:'#333',fontSize:12}} 56 | selectedTitleStyle={{color:'rgb(251,33,33)'}} 57 | allowFontScaling={true} 58 | > 59 | 60 | 61 | ) 62 | }) 63 | } 64 | 65 | ) 66 | } 67 | } 68 | 69 | 70 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Common/Config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/14. 3 | */ 4 | 'use strict' 5 | 6 | const token ={ 7 | 'showapi_appid' : '27786', 8 | 'showapi_sign' : '8435f098f5b74384ba294790c7e8b503', 9 | }; 10 | 11 | const config = { 12 | 13 | api:{ 14 | homeList:'http://route.showapi.com/255-1?showapi_appid='+token.showapi_appid+ 15 | '&showapi_sign=' + token.showapi_sign 16 | }, 17 | map:{ 18 | method:'POST', 19 | header:{ 20 | 'Accept-Encoding':'gzip, deflate', 21 | 'Content-Type':'application/json', 22 | 'User-Agent':'11', 23 | 'X-Device-ID':'111', 24 | 'X-Ip':'111', 25 | 26 | }, 27 | // body:JSON.stringify(body), 28 | follow:20, 29 | timeout:8000, 30 | size:0 31 | }, 32 | }; 33 | 34 | // const token = { 35 | // 'showapi_appid' : '27786', 36 | // 'showapi_sign' : '8435f098f5b74384ba294790c7e8b503', 37 | // }; 38 | 39 | module.exports = config; 40 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Common/ConnectComponent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 作者:paozi 3 | * 创建:2016/10/16 4 | * 修改: 5 | * 描述:容器连接 6 | */ 7 | import { connect } from 'react-redux'; 8 | import { bindActionCreators } from 'redux'; 9 | import actions from '../Actions/Index'; 10 | 11 | 12 | const options = { 13 | withRef: true 14 | }; 15 | 16 | 17 | export default function connectComponent({ mapStateToProps, mapDispatchToProps, mergeProps, LayoutComponent }) { 18 | return connect( 19 | mapStateToProps || function (state) { 20 | return {}; 21 | }, 22 | mapDispatchToProps || function (dispatch) { 23 | return { 24 | actions: bindActionCreators(actions, dispatch) 25 | } 26 | }, 27 | mergeProps, 28 | options 29 | )(LayoutComponent); 30 | } 31 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Common/HomeContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | import React from 'react'; 5 | import {connect} from 'react-redux'; 6 | import Home from '../Pages/News/News'; 7 | 8 | class HomeContainer extends React.Component { 9 | render() { 10 | return ( 11 | 12 | ) 13 | } 14 | } 15 | 16 | export default connect((state) => { 17 | const { Home } = state; 18 | return { 19 | Home 20 | } 21 | }) 22 | (HomeContainer); -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Common/Loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ljunb on 16/6/2. 3 | */ 4 | import React from 'react'; 5 | import { 6 | StyleSheet, 7 | View, 8 | Text, 9 | ActivityIndicator, 10 | } from 'react-native'; 11 | 12 | // import Common from '../common/common'; 13 | 14 | export default class Loading extends React.Component { 15 | render() { 16 | return ( 17 | 18 | 19 | 加载中…… 20 | 21 | ) 22 | } 23 | } 24 | 25 | const styles = StyleSheet.create({ 26 | loading: { 27 | backgroundColor: 'gray', 28 | height: 80, 29 | width: 100, 30 | borderRadius: 10, 31 | justifyContent: 'center', 32 | alignItems: 'center', 33 | position: 'absolute', 34 | // top: (Common.window.height-80)/2, 35 | // left: (Common.window.width-100)/2, 36 | }, 37 | 38 | loadingTitle: { 39 | marginTop: 10, 40 | fontSize: 14, 41 | color: 'white' 42 | } 43 | }) -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Common/Request.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/14. 3 | */ 4 | 'use strict' 5 | import queryString from 'query-string'; 6 | 7 | let request = { 8 | get:(url ,params , successCallBack , failCallBack) =>{ 9 | if (params){ 10 | url += '&' + queryString.stringify(params) 11 | } 12 | console.log(url); 13 | return fetch(url) 14 | .then((response) => response.json()) 15 | .then((response) => { 16 | successCallBack(response); 17 | }) 18 | .catch ((error) => { 19 | failCallBack(error); 20 | }); 21 | } 22 | }; 23 | 24 | module.exports = request; 25 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/Main/Main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | InteractionManager, 14 | ListView, 15 | AlertIOS 16 | } from 'react-native'; 17 | 18 | import NavBar from 'react-native-navbar'; 19 | import LeftNavBtn from '../../../../../Base/Component/leftNavBtn'; 20 | 21 | // import Wilddog from 'wilddog'; 22 | 23 | import {styles} from './styles'; 24 | import {ActionButton} from './components/ActionButton' 25 | import {ListItem} from './components/ListItem' 26 | import {StatusBar} from './components/StatusBar' 27 | 28 | const Wilddog = require('wilddog'); 29 | const WilddogUrl = 'https://scm.wilddogio.com/'; 30 | 31 | export default class Main extends Component { 32 | 33 | constructor(props) { 34 | super(props); 35 | this.state = { 36 | dataSource: new ListView.DataSource({ 37 | rowHasChanged: (row1, row2) => row1 !== row2 38 | }) 39 | }; 40 | this.itemsRef = Main.getRef().child('items'); 41 | } 42 | 43 | static getRef() { 44 | return new Wilddog(WilddogUrl); 45 | } 46 | 47 | render() { 48 | return ( 49 | 50 | 51 | 55 | 56 | 57 | ); 58 | } 59 | 60 | componentDidMount() { 61 | this.listenForItems(this.itemsRef); 62 | } 63 | 64 | // 这里就是让这个 ListItem 活起来的关键所有在了 65 | listenForItems(itemsRef) { 66 | itemsRef.on('value', (snap) => { 67 | 68 | // get children as an array 69 | var items = []; 70 | snap.forEach((child) => { 71 | items.push({ 72 | title: child.val().title, 73 | _key: child.key() 74 | }); 75 | }); 76 | 77 | this.setState({ 78 | dataSource: this.state.dataSource.cloneWithRows(items) 79 | }); 80 | 81 | }); 82 | } 83 | 84 | // 新建条目的时候只需要向 wilddog 写入数据即可, 因为我们在前面调用了 itemsRef.on('value'), wilddog 数据库中的改动会被自动 85 | // 同步到本地进行处理 86 | _addItem() { 87 | AlertIOS.prompt( 88 | '新增条目', 89 | '请输入要添加的条目名称', 90 | [ 91 | { 92 | text: '确认', 93 | onPress: (text) => { 94 | this.itemsRef.push({title: text}) 95 | } 96 | } 97 | ], 98 | 'plain-text' 99 | ); 100 | } 101 | 102 | _renderItem(item) { 103 | const onPress = () => { 104 | AlertIOS.prompt( 105 | '删除条目', 106 | '确认删除 ' + item.title + ' 吗?', 107 | [ 108 | {text: '删除', onPress: (text) => this.itemsRef.child(item._key).remove()}, 109 | {text: '取消', onPress: (text) => console.log('已取消')} 110 | ], 111 | 'default' 112 | ); 113 | }; 114 | return ( 115 | 116 | ); 117 | } 118 | 119 | 120 | 121 | // render() { 122 | // var titleConfig = { 123 | // title: '我的', 124 | // style: {color:'black',fontSize:18 ,fontWeight:'500'} 125 | // }; 126 | // return ( 127 | // 128 | // 132 | // 133 | // ); 134 | // } 135 | } 136 | 137 | 138 | const styles1 = StyleSheet.create({ 139 | container: { 140 | flex: 1, 141 | backgroundColor: '#F5FCFF', 142 | }, 143 | welcome: { 144 | fontSize: 20, 145 | textAlign: 'center', 146 | margin: 10, 147 | }, 148 | instructions: { 149 | textAlign: 'center', 150 | color: '#333333', 151 | marginBottom: 5, 152 | }, 153 | }); 154 | 155 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/Main/components/ActionButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jale on 16/6/3. 3 | */ 4 | import React, { Component} from 'react'; 5 | import { 6 | View,TouchableHighlight,Text 7 | } from 'react-native'; 8 | 9 | 10 | import {styles,constants} from '../styles' 11 | 12 | class ActionButton extends Component { 13 | render() { 14 | return ( 15 | 16 | 19 | {this.props.title} 20 | 21 | 22 | ); 23 | } 24 | } 25 | 26 | export {ActionButton}; -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/Main/components/ListItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jale on 16/6/3. 3 | */ 4 | import React, {Component} from 'react'; 5 | import { 6 | View,TouchableHighlight,Text 7 | } from 'react-native'; 8 | 9 | 10 | import {styles,constants} from '../styles' 11 | 12 | class ListItem extends React.Component { 13 | render() { 14 | return ( 15 | 16 | 17 | {this.props.item.title} 18 | 19 | 20 | ); 21 | } 22 | } 23 | 24 | export {ListItem} -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/Main/components/StatusBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jale on 16/6/3. 3 | */ 4 | 5 | import React, {Component} from 'react'; 6 | import { 7 | View,Text 8 | } from 'react-native'; 9 | 10 | import {styles,constants} from '../styles' 11 | 12 | class StatusBar extends React.Component { 13 | render() { 14 | return ( 15 | 16 | 17 | 18 | {this.props.title} 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | export {StatusBar} -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/Main/styles.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jale on 16/6/3. 3 | */ 4 | 5 | import { 6 | StyleSheet 7 | } from 'react-native'; 8 | 9 | const constants = { 10 | actionColor: '#24CE84' 11 | }; 12 | 13 | var styles = StyleSheet.create({ 14 | container: { 15 | backgroundColor: '#f2f2f2', 16 | flex: 1 17 | }, 18 | listview: { 19 | flex: 1 20 | }, 21 | li: { 22 | backgroundColor: '#fff', 23 | borderBottomColor: '#eee', 24 | borderColor: 'transparent', 25 | borderWidth: 1, 26 | paddingLeft: 16, 27 | paddingTop: 14, 28 | paddingBottom: 16 29 | }, 30 | liContainer: { 31 | flex: 2 32 | }, 33 | liText: { 34 | color: '#333', 35 | fontSize: 16 36 | }, 37 | navbar: { 38 | alignItems: 'center', 39 | backgroundColor: '#fff', 40 | borderBottomColor: '#eee', 41 | borderColor: 'transparent', 42 | borderWidth: 1, 43 | justifyContent: 'center', 44 | height: 44, 45 | flexDirection: 'row' 46 | }, 47 | navbarTitle: { 48 | color: '#444', 49 | fontSize: 16, 50 | fontWeight: "500" 51 | }, 52 | statusbar: { 53 | backgroundColor: '#fff', 54 | height: 22 55 | }, 56 | center: { 57 | textAlign: 'center' 58 | }, 59 | actionText: { 60 | color: '#fff', 61 | fontSize: 16, 62 | textAlign: 'center' 63 | }, 64 | action: { 65 | backgroundColor: constants.actionColor, 66 | borderColor: 'transparent', 67 | borderWidth: 1, 68 | paddingLeft: 16, 69 | paddingTop: 14, 70 | paddingBottom: 16 71 | }, 72 | actionItem: { 73 | alignSelf: "stretch" 74 | } 75 | }); 76 | 77 | export {constants, styles}; 78 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/News/News.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | InteractionManager 14 | } from 'react-native'; 15 | 16 | import ScrollableTabView, {DefaultTabBar, ScrollableTabBar} from 'react-native-scrollable-tab-view'; 17 | import NewsList from './NewsList'; 18 | import NavBar from 'react-native-navbar'; 19 | 20 | export default class News extends Component { 21 | 22 | static defaultProps = { 23 | 'showapi_appid' : '27786', 24 | 'showapi_sign' : '8435f098f5b74384ba294790c7e8b503' 25 | }; 26 | 27 | constructor(props){ 28 | super(props); 29 | this.state = { 30 | typeArr : [ 31 | { 32 | 'title':'全部', 33 | 'type':'', 34 | }, 35 | { 36 | 'title':'视频', 37 | 'type':'41', 38 | }, 39 | { 40 | 'title':'图片', 41 | 'type':'10', 42 | }, 43 | { 44 | 'title':'段子', 45 | 'type':'29', 46 | }, 47 | { 48 | 'title':'声音 ', 49 | 'type':'31', 50 | }, 51 | ], 52 | } 53 | } 54 | 55 | render() { 56 | var titleConfig = { 57 | title: '新闻', 58 | style: {color: 'black', fontSize: 18, fontWeight: '500'} 59 | }; 60 | 61 | return ( 62 | 63 | 67 | { 68 | this.state.typeArr.length > 0 ? 69 | }> 71 | { 72 | this.state.typeArr.map((item, i) => { 73 | return ( 74 | 76 | ) 77 | }) 78 | } 79 | : null 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | ); 88 | 89 | } 90 | } 91 | 92 | 93 | const styles = StyleSheet.create({ 94 | container: { 95 | flex: 1, 96 | 97 | backgroundColor: '#F5FCFF', 98 | }, 99 | welcome: { 100 | fontSize: 20, 101 | textAlign: 'center', 102 | margin: 10, 103 | }, 104 | instructions: { 105 | textAlign: 'center', 106 | color: '#333333', 107 | marginBottom: 5, 108 | }, 109 | }); 110 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/News/NewsDetail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | InteractionManager, 14 | WebView 15 | } from 'react-native'; 16 | 17 | import NavBar from 'react-native-navbar'; 18 | 19 | import LeftNavBtn from '../../../../../Base/Component/leftNavBtn'; 20 | 21 | var WEBVIEW_REF = 'webview'; 22 | var DEFAULT_URL = 'https://m.facebook.com'; 23 | var TEXT_INPUT_REF = 'urlInput'; 24 | 25 | export default class NewsDetail extends Component { 26 | popToHome(){ 27 | InteractionManager.runAfterInteractions(()=>{ 28 | this.props.navigator.pop(); 29 | }); 30 | } 31 | render() { 32 | 33 | var titleConfig = { 34 | title: '新闻详情', 35 | style: {color: 'black', fontSize: 18, fontWeight: '500'} 36 | }; 37 | return ( 38 | 39 | this.popToHome()} 45 | /> 46 | } 47 | /> 48 | 57 | 58 | ); 59 | } 60 | } 61 | 62 | 63 | const styles = StyleSheet.create({ 64 | container: { 65 | flex: 1, 66 | backgroundColor: '#F5FCFF', 67 | }, 68 | welcome: { 69 | fontSize: 20, 70 | textAlign: 'center', 71 | margin: 10, 72 | }, 73 | instructions: { 74 | textAlign: 'center', 75 | color: '#333333', 76 | marginBottom: 5, 77 | }, 78 | }); 79 | 80 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/News/NewsItem.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | Image, 14 | Dimensions, 15 | TouchableOpacity 16 | } from 'react-native'; 17 | 18 | var {width, height} = Dimensions.get('window'); 19 | 20 | export default class NewsItem extends Component { 21 | static defaultProps = { 22 | contentObj: {}, 23 | }; 24 | 25 | constructor(props){ 26 | super(props); 27 | this.state = { 28 | newText:'', 29 | } 30 | } 31 | picturePress(){ 32 | return( 33 | 34 | 2222 35 | 36 | ) 37 | } 38 | 39 | componentDidMount(){ 40 | this.renderReplace(); 41 | } 42 | // 处理文字 43 | renderReplace(){ 44 | let text = this.props.contentObj.text; 45 | if (text.replace('\n')){ 46 | text = text.replace('\n',''); 47 | text = text.replace('\n',''); 48 | text = text.replace('\n',''); 49 | text = text.replace('\n',''); 50 | text = text.replace('\n',''); 51 | } 52 | this.setState({ 53 | newText:text 54 | }) 55 | } 56 | // 搞笑段子 57 | renderFunny(){ 58 | return( 59 | 60 | 61 | {this.state.newText} 62 | 63 | 64 | ) 65 | } 66 | // 搞笑视频 67 | renderVideo(){ 68 | return( 69 | 70 | {this.state.newText} 71 | 72 | 73 | ) 74 | } 75 | // 搞笑图片 76 | renderPicture(){ 77 | return( 78 | this.picturePress()}> 79 | 80 | 81 | {this.state.newText} 82 | 83 | 84 | 85 | 86 | ) 87 | } 88 | // 搞笑声音 89 | renderMusic(){ 90 | return( 91 | 92 | 93 | {this.state.newText} 94 | 95 | 96 | ) 97 | } 98 | 99 | // 全部cell 100 | renderCell(){ 101 | //视频 102 | if (this.props.contentObj.type == '41'){ 103 | return( 104 | 105 | {this.renderVideo()} 106 | 107 | ) 108 | } 109 | // 图片 110 | if (this.props.contentObj.type == '10'){ 111 | return( 112 | 113 | {this.renderPicture()} 114 | 115 | ) 116 | } 117 | // 搞笑段子 118 | if (this.props.contentObj.type == '29'){ 119 | return ( 120 | {this.renderFunny()} 121 | ) 122 | } 123 | // 声音 124 | if (this.props.contentObj.type == '31'){ 125 | return( 126 | 127 | {this.renderMusic()} 128 | 129 | ) 130 | } 131 | 132 | } 133 | 134 | render() { 135 | return ( 136 | 137 | {this.renderCell()} 138 | 139 | 140 | ); 141 | } 142 | } 143 | 144 | 145 | const styles = StyleSheet.create({ 146 | container: { 147 | width:width, 148 | backgroundColor: 'white', 149 | 150 | }, 151 | lineStyle: { 152 | backgroundColor:'#ddd', 153 | height:1, 154 | marginLeft:10, 155 | marginRight:10 156 | }, 157 | textStyle: { 158 | fontSize:18, 159 | margin:10, 160 | } 161 | 162 | }); 163 | 164 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Pages/News/NewsList.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/24. 3 | */ 4 | /** 5 | * Sample React Native App 6 | * https://github.com/facebook/react-native 7 | * @flow 8 | */ 9 | 10 | import React, { Component } from 'react'; 11 | import { 12 | AppRegistry, 13 | StyleSheet, 14 | Text, 15 | View, 16 | ListView, 17 | InteractionManager, 18 | RefreshControl 19 | } from 'react-native'; 20 | 21 | import { 22 | Home, 23 | } from '../../Actions/HomeAction'; 24 | 25 | import NewsItem from './NewsItem'; 26 | import NewsDetail from './NewsDetail'; 27 | 28 | // import Loading from '../../Common/Loading'; 29 | 30 | 31 | // let channelId = this.props.channelId; 32 | let page = 0; 33 | let isLoadMore = false; 34 | let isRefreshing = false; 35 | let isLoading = true; 36 | 37 | export default class NewsList extends Component { 38 | static defaultProps = { 39 | 'showapi_appid' : '27786', 40 | 'showapi_sign' : '8435f098f5b74384ba294790c7e8b503', 41 | 'type' : '', 42 | }; 43 | 44 | constructor(props){ 45 | super(props); 46 | var dataSource = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2}); 47 | this.state = { 48 | dataSource : dataSource, 49 | isRefreshing : false, 50 | isLoadMore: false, 51 | allPages: '', 52 | allNum : '', 53 | currentPage:'', 54 | }; 55 | this.renderRow = this.renderRow.bind(this); 56 | this.onRefresh = this.onRefresh.bind(this); 57 | this.onEndReached = this.onEndReached.bind(this); 58 | this.renderFooter = this.renderFooter.bind(this); 59 | } 60 | 61 | // 服务器有没有更多数据 62 | isMore(){ 63 | console.log(this.state.allPage !== this.state.currentPage); 64 | // 全部页数不等于当前页数,那就说明有更多数据 65 | return this.state.allPage !== this.state.currentPage; 66 | } 67 | renderFooter(){ 68 | console.log('这是底部View'); 69 | if (!this.isMore() && this.state.allPage !== 0 ){ 70 | return ( 71 | 72 | 没有更多数据了 73 | 74 | ) 75 | } 76 | 77 | if (!this.state.isLoadingMore){ 78 | return 79 | } 80 | 81 | return( 82 | 85 | ) 86 | } 87 | 88 | onEndReached(){ 89 | console.log('这是底部加载数据'); 90 | if (!this.isMore() || this.state.isLoadingMore ){ 91 | return; 92 | } 93 | // 去服务器请求加载更多数据 94 | let page = this.setState({ 95 | currentPage : this.state.currentPage + 1 96 | }); 97 | 98 | page = this.state.currentPage; 99 | const {dispatch} = this.props; 100 | isLoadMore = false; 101 | this.setState({ 102 | isLoadMore : true 103 | }); 104 | console.log(this.state.isRefreshing); 105 | isLoading= false; 106 | console.log(page, this.props.type, isLoadMore, this.state.isRefreshing, isLoading); 107 | dispatch(Home(page, this.props.type, isLoadMore, this.state.isRefreshing, isLoading,(arr)=>{ 108 | // console.log(arr); 109 | this.setState({ 110 | dataSource: this.state.dataSource.cloneWithRows(arr['contentlist']), 111 | isRefreshing:false, 112 | currentPage:arr.currentPage, 113 | isLoadMore : false 114 | }); 115 | })); 116 | 117 | } 118 | 119 | onRefresh(){ 120 | page = 1; 121 | const {dispatch} = this.props; 122 | isLoadMore = false; 123 | this.setState({ 124 | isRefreshing : true 125 | }); 126 | console.log(this.state.isRefreshing); 127 | isLoading= false; 128 | console.log(page, this.props.type, isLoadMore, this.state.isRefreshing, isLoading); 129 | dispatch(Home(page, this.props.type, isLoadMore, this.state.isRefreshing, isLoading,(arr)=>{ 130 | // console.log(arr); 131 | this.setState({ 132 | dataSource: this.state.dataSource.cloneWithRows(arr['contentlist']), 133 | isRefreshing:false, 134 | currentPage:arr.currentPage, 135 | }); 136 | })); 137 | } 138 | 139 | pushPage(rowData){ 140 | let {navigator} = this.props; 141 | if (navigator) { 142 | InteractionManager.runAfterInteractions(()=> { 143 | navigator.push({ 144 | component: NewsDetail, 145 | passProps:{ 146 | link:rowData.link, 147 | } 148 | }) 149 | }); 150 | } 151 | } 152 | componentDidMount() { 153 | InteractionManager.runAfterInteractions(() => { 154 | const {dispatch} = this.props; 155 | dispatch(Home(page,this.props.type,isLoadMore,isRefreshing,isLoading, (arr) => { 156 | console.log(arr['contentlist'][0]['text']); 157 | this.setState({ 158 | dataSource: this.state.dataSource.cloneWithRows(arr['contentlist']), 159 | allPages:arr.allPages, 160 | allNum:arr.allNum, 161 | currentPage:arr.currentPage, 162 | }) 163 | })) 164 | }) 165 | } 166 | 167 | loadData(page){ 168 | 169 | this.setState({ 170 | isRefreshing :true 171 | }); 172 | 173 | let url = 'http://route.showapi.com/109-35?showapi_appid='+this.props.showapi_appid+ 174 | '&showapi_sign='+this.props.showapi_sign+'&channelId='+this.props.channelId+ 175 | '&needAllList=0&maxResult=20&page='; 176 | // console.log(url); 177 | fetch(url) 178 | .then((response) => response.json()) 179 | .then((responseData)=> { 180 | console.log(responseData); 181 | this.setState({ 182 | dataSource: this.state.dataSource.cloneWithRows(responseData['showapi_res_body']['pagebean']['contentlist']) 183 | }); 184 | 185 | }); 186 | } 187 | 188 | renderRow(rowData){ 189 | return( 190 | 193 | ) 194 | } 195 | render() { 196 | const {Home,rowData} = this.props; 197 | // let homeList=[]; 198 | // let homeList = this.state.dataSource.cloneWithRows(Home.HomeList); 199 | // console.log(Home.HomeList.length); 200 | // console.log(Home.isRefreshing); 201 | return ( 202 | 203 | 214 | } 215 | onEndReached={this.onEndReached} 216 | onEndReachedThreshold={40} 217 | renderFooter={this.renderFooter} 218 | /> 219 | 220 | ); 221 | } 222 | } 223 | 224 | 225 | const styles = StyleSheet.create({ 226 | container: { 227 | flex: 1, 228 | backgroundColor: '#F5FCFF', 229 | }, 230 | welcome: { 231 | fontSize: 20, 232 | textAlign: 'center', 233 | margin: 10, 234 | }, 235 | instructions: { 236 | textAlign: 'center', 237 | color: '#333333', 238 | marginBottom: 5, 239 | }, 240 | }); 241 | 242 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Reducers/HomeReducer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | import * as types from '../Actions/ActionTypes'; 5 | 6 | const initialState = { 7 | HomeList: [], 8 | isLoading: true, 9 | isLoadMore: false, 10 | isRefreshing: false, 11 | }; 12 | 13 | let HomeReducer = (state = initialState, action) => { 14 | 15 | switch (action.type) { 16 | case types.FETCH_HOME_LIST: 17 | return Object.assign({} , state ,{ 18 | isLoadMore:action.isLoadMore, 19 | isRefreshing:action.isRefreshing, 20 | isLoading:action.isLoading 21 | }); 22 | case types.RECEIVE_HOME_LIST: 23 | return Object.assign({} , state, { 24 | HomeList:state.isLoadMore ? state.HomeList.concat(action.homeList) : action.homeList, 25 | isRefreshing:false, 26 | isLoading:false, 27 | }); 28 | case types.RESET_STATE: 29 | return Object.assign({},state,{ 30 | HomeList:[], 31 | isLoading:true, 32 | }); 33 | default: 34 | return state; 35 | } 36 | }; 37 | 38 | export default HomeReducer; 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Reducers/RootReducer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | import { combineReducers } from 'redux'; 5 | import Home from './HomeReducer'; 6 | 7 | export default RootReducer = combineReducers({ 8 | Home, 9 | }); 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Resource/main-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/FivePage/Component/Resource/main-normal.png -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Resource/main-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/FivePage/Component/Resource/main-selected.png -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Resource/news-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/FivePage/Component/Resource/news-normal.png -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Resource/news-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/FivePage/Component/Resource/news-selected.png -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Component/Store/Store.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/12/1. 3 | */ 4 | import { createStore, applyMiddleware} from 'redux'; 5 | import thunk from 'redux-thunk'; 6 | import RootReducer from '../Reducers/RootReducer'; 7 | 8 | let createStoreWithMiddleware = applyMiddleware(thunk)(createStore); 9 | let store = createStoreWithMiddleware(RootReducer); 10 | // let state = store.getState(); 11 | // alert(state.Search.searchText) 12 | export default store; -------------------------------------------------------------------------------- /Example/App/Page/FivePage/Five.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/23. 3 | */ 4 | /** 5 | * Sample React Native App 6 | * https://github.com/facebook/react-native 7 | * @flow 8 | */ 9 | 10 | import React, { Component } from 'react'; 11 | import { Provider } from 'react-redux'; 12 | import Store from './Component/Store/Store'; 13 | 14 | import Root from './Component/Base/Root'; 15 | 16 | export default class Five extends Component { 17 | 18 | render() { 19 | return ( 20 | 21 | 22 | 23 | ); 24 | } 25 | } 26 | 27 | 28 | // AppRegistry.registerComponent('Five', () => Five); 29 | -------------------------------------------------------------------------------- /Example/App/Page/FourPage/Four.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | import NavBar from 'react-native-navbar'; 15 | import LeftNavBtn from '../../Base/Component/leftNavBtn' 16 | 17 | 18 | export default class Four extends Component { 19 | // 组件加载完成 20 | render() { 21 | var titleConfig = { 22 | title: '生命周期', 23 | style: {color:'black',fontSize:18,fontWeight:'500'} 24 | }; 25 | return ( 26 | 27 | this.popToHome()} 33 | /> 34 | } 35 | /> 36 | 37 | 38 | ); 39 | } 40 | popToHome(){ 41 | this.props.navigator.popToTop(); 42 | } 43 | } 44 | 45 | class Detail extends Component { 46 | // 组件要不要更新 47 | shouldComponentUpdate() { 48 | console.log('shouldComponentUpdate','组件要不要更新'); 49 | return true; 50 | } 51 | // 组件将要更新 52 | componentWillUpdate(){ 53 | console.log('componentWillUpdate','组件将要更新'); 54 | } 55 | 56 | // 即将拿到组件的更新 57 | componentWillReceiveProps(props) { 58 | console.log('componentWillReceiveProps',props); 59 | } 60 | 61 | // 组件已经更新 62 | componentDidUpdate() { 63 | console.log('componentDidUpdate','组件更新完成'); 64 | } 65 | 66 | // 组件将要加载 67 | componentWillMount() { 68 | console.log('componentWillMount','组件将要加载'); 69 | } 70 | 71 | // 在调用render之后,组件已经加载 72 | componentDidMount() { 73 | console.log('componentDidMount','组件加载完成'); 74 | } 75 | // 组件初始之前的值 76 | static defaultProps = { 77 | number : 1 78 | }; 79 | // 组件初始的值 80 | constructor(props){ 81 | console.log(props,'组件初始之前的值'); 82 | super(props); 83 | this.state = { 84 | number : this.props.number 85 | }; 86 | console.log(this.state.number,'state初始的值'); 87 | } 88 | render() { 89 | console.log('render','组件加载'); 90 | return ( 91 | 92 | 点击我呀! 93 | {this.state.number} 94 | (主要看控制台打印哦~) 95 | 96 | ); 97 | } 98 | onTextClick(){ 99 | var number = this.state.number; 100 | number ++; 101 | this.setState({ 102 | number:number 103 | }) 104 | console.log(this.state.number,'state变更的值'); 105 | } 106 | } 107 | 108 | const styles = StyleSheet.create({ 109 | container: { 110 | flex: 1, 111 | backgroundColor:'white' 112 | }, 113 | TextStyle : { 114 | alignItems:'center', 115 | justifyContent: 'center', 116 | alignSelf:'center', 117 | height:50, 118 | marginTop:10, 119 | fontSize:20, 120 | } 121 | }); 122 | 123 | AppRegistry.registerComponent('Example', () => Four); -------------------------------------------------------------------------------- /Example/App/Page/SixPage/Six.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import {Provider} from 'react-redux'; 9 | import store from './store/store'; 10 | 11 | import Root from './base/root' 12 | 13 | export default class Six extends Component { 14 | render() { 15 | 16 | return ( 17 | 18 | 19 | 20 | ); 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/actions/actionTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/30. 3 | */ 4 | //主页actions 5 | export const FETCH_HOME_LIST = 'FETCH_HOME_LIST'; 6 | export const RECEIVE_HOME_LIST = 'RECEIVE_HOME_LIST'; 7 | 8 | 9 | //分类页actions 10 | export const FETCH_MAIN_LIST = 'FETCH_MAIN_LIST'; 11 | export const RECEIVE_MAIN_LIST = 'RECEIVE_MAIN_LIST'; -------------------------------------------------------------------------------- /Example/App/Page/SixPage/actions/homeAction.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import * as types from './actionTypes'; 4 | import Util from '../common/utils'; 5 | 6 | export let home = (tag, offest, limit, isLoadMore, isRefreshing, isLoading) => { 7 | let URL = 'http://api.huaban.com/fm/wallpaper/pins?limit='; 8 | if (limit) URL += limit; 9 | offest ? URL += '&max=' + offest : URL += '&max='; 10 | tag ? URL += '&tag=' + encode_utf8(tag) : URL += '&tag=' 11 | // console.log(URL) 12 | 13 | return dispatch => { 14 | dispatch(feachHomeList(isLoadMore, isRefreshing, isLoading)); 15 | return Util.get(URL, (response) => { 16 | // console.log(response) 17 | // debugger 18 | dispatch(receiveHomeList(response.pins)) 19 | }, (error) => { 20 | console.log('加载首页数据error==>' + error); 21 | // // debugger 22 | dispatch(receiveHomeList([])); 23 | }); 24 | 25 | } 26 | }; 27 | 28 | function encode_utf8(s) { 29 | return encodeURIComponent(s); 30 | } 31 | 32 | let feachHomeList = (isLoadMore, isRefreshing, isLoading) => { 33 | return { 34 | type: types.FETCH_HOME_LIST, 35 | isLoadMore: isLoadMore, 36 | isRefreshing: isRefreshing, 37 | isLoading: isLoading, 38 | } 39 | }; 40 | 41 | let receiveHomeList = (homeList) => { 42 | return { 43 | type: types.RECEIVE_HOME_LIST, 44 | homeList: homeList, 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/base/root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View, 13 | Navigator 14 | } from 'react-native'; 15 | 16 | import TabBarView from './tabBarView'; 17 | 18 | export default class Root extends Component { 19 | render() { 20 | return ( 21 | 22 | { 26 | if (route.sceneConfig) { 27 | return route.sceneConfig; 28 | } 29 | return Navigator.SceneConfigs.PushFromRight; 30 | } } 31 | renderScene={(route, navigator) => { 32 | let Component = route.component; 33 | return ( 34 | 35 | ) 36 | } } 37 | /> 38 | 39 | ); 40 | } 41 | } 42 | 43 | 44 | const styles = StyleSheet.create({ 45 | container: { 46 | flex: 1, 47 | justifyContent: 'center', 48 | alignItems: 'center', 49 | backgroundColor: '#F5FCFF', 50 | }, 51 | welcome: { 52 | fontSize: 20, 53 | textAlign: 'center', 54 | margin: 10, 55 | }, 56 | instructions: { 57 | textAlign: 'center', 58 | color: '#333333', 59 | marginBottom: 5, 60 | }, 61 | }); 62 | 63 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/base/tabBarView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 16/9/10. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | View, 7 | Text, 8 | Image, 9 | } from 'react-native'; 10 | 11 | import TabNavigator from 'react-native-tab-navigator'; 12 | import Home from '../containers/homeContainer'; 13 | import Main from '../containers/detail'; 14 | 15 | 16 | 17 | const tabBarItems = [ 18 | { title: '新闻', icon: () => , 19 | selectedIcon: () => 20 | ,component: Home }, 21 | { title: '我的', icon: () => , 22 | selectedIcon: () => , 23 | component: Main }, 24 | // { title: '关于', icon: () => , Component: HomeContainer }, 25 | ] 26 | 27 | export default class TabBarView extends Component { 28 | constructor(props) { 29 | super(props); 30 | this.state = { 31 | selectedTab: tabBarItems[0].title, 32 | }; 33 | } 34 | render(){ 35 | return( 36 | 37 | { 38 | tabBarItems.map((controller,i) => { 39 | let Component = controller.component; 40 | return( 41 | this.setState({selectedTab:controller.title})} 48 | titleStyle={{color:'#333',fontSize:12}} 49 | selectedTitleStyle={{color:'rgb(251,33,33)'}} 50 | allowFontScaling={true} 51 | > 52 | 53 | 54 | ) 55 | }) 56 | } 57 | 58 | ) 59 | } 60 | } 61 | 62 | 63 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/common/HeaderView.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ljunb on 16/5/8. 3 | * 导航栏标题 4 | */ 5 | import React from 'react'; 6 | import { 7 | StyleSheet, 8 | View, 9 | Text, 10 | Image, 11 | TouchableOpacity, 12 | } from 'react-native'; 13 | 14 | import Icon from 'react-native-vector-icons/FontAwesome'; 15 | import Common from '../common/common'; 16 | 17 | export default class Header extends React.Component { 18 | 19 | render() { 20 | 21 | let NavigationBar = []; 22 | 23 | // 左边图片按钮 24 | if (this.props.leftIcon != undefined) { 25 | NavigationBar.push( 26 | 32 | 33 | 34 | ) 35 | } 36 | 37 | // 标题 38 | if (this.props.title != undefined) { 39 | NavigationBar.push( 40 | {this.props.title} 41 | ) 42 | } 43 | 44 | // 自定义标题View 45 | if (this.props.titleView != undefined) { 46 | let Component = this.props.titleView; 47 | 48 | NavigationBar.push( 49 | {this.props.titleView} 50 | ) 51 | } 52 | 53 | 54 | return ( 55 | 56 | {NavigationBar} 57 | 58 | ) 59 | } 60 | } 61 | 62 | const styles = StyleSheet.create({ 63 | 64 | navigationBarContainer: { 65 | marginTop: 20, 66 | flexDirection: 'row', 67 | height: 44, 68 | justifyContent: 'center', 69 | alignItems: 'center', 70 | borderBottomColor: '#ccc', 71 | borderBottomWidth: 0.5, 72 | backgroundColor: 'white' 73 | }, 74 | 75 | title: { 76 | fontSize: 15, 77 | marginLeft: 15, 78 | }, 79 | titleView: { 80 | fontSize: 15, 81 | }, 82 | leftIcon: { 83 | position:'absolute', 84 | left:10, 85 | top:5 86 | }, 87 | 88 | }) -------------------------------------------------------------------------------- /Example/App/Page/SixPage/common/LoadMoreFooter.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ljunb on 16/5/30. 3 | */ 4 | import React from 'react'; 5 | import { 6 | ActivityIndicator, 7 | View, 8 | Text, 9 | StyleSheet, 10 | } from 'react-native'; 11 | 12 | export default class LoadMoreFooter extends React.Component { 13 | render() { 14 | return ( 15 | 16 | 17 | 正在加载更多…… 18 | 19 | ) 20 | } 21 | } 22 | 23 | const styles = StyleSheet.create({ 24 | footer: { 25 | flexDirection: 'row', 26 | justifyContent: 'center', 27 | alignItems: 'center', 28 | height: 40, 29 | }, 30 | 31 | footerTitle: { 32 | marginLeft: 10, 33 | fontSize: 15, 34 | color: 'gray' 35 | } 36 | }) -------------------------------------------------------------------------------- /Example/App/Page/SixPage/common/Loading.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by ljunb on 16/6/2. 3 | */ 4 | import React from 'react'; 5 | import { 6 | StyleSheet, 7 | View, 8 | Text, 9 | ActivityIndicator, 10 | } from 'react-native'; 11 | 12 | import Common from '../common/common'; 13 | 14 | export default class Loading extends React.Component { 15 | render() { 16 | return ( 17 | 18 | 19 | 加载中…… 20 | 21 | ) 22 | } 23 | } 24 | 25 | const styles = StyleSheet.create({ 26 | loading: { 27 | backgroundColor: 'gray', 28 | height: 80, 29 | width: 100, 30 | borderRadius: 10, 31 | justifyContent: 'center', 32 | alignItems: 'center', 33 | position: 'absolute', 34 | top: (Common.window.height-80)/2, 35 | left: (Common.window.width-100)/2, 36 | }, 37 | 38 | loadingTitle: { 39 | marginTop: 10, 40 | fontSize: 14, 41 | color: 'white' 42 | } 43 | }) -------------------------------------------------------------------------------- /Example/App/Page/SixPage/common/common.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by jsaon on 16/7/15. 3 | */ 4 | import {Dimensions} from 'react-native'; 5 | 6 | let window = { 7 | width: Dimensions.get('window').width, 8 | height: Dimensions.get('window').height, 9 | } 10 | export default { 11 | window: window, 12 | } -------------------------------------------------------------------------------- /Example/App/Page/SixPage/common/utils.js: -------------------------------------------------------------------------------- 1 | 2 | let Util = { 3 | /* 4 | * fetch简单封装 5 | * url: 请求的URL 6 | * successCallback: 请求成功回调 7 | * failCallback: 请求失败回调 8 | * 9 | * */ 10 | get: (url, successCallback, failCallback) => { 11 | fetch(url) 12 | .then((response) => response.text()) 13 | .then((responseText) => { 14 | successCallback(JSON.parse(responseText)); 15 | }) 16 | .catch((err) => { 17 | failCallback(err); 18 | }); 19 | }, 20 | gets: (url, successCallback, failCallback) => { 21 | var request = new XMLHttpRequest(); 22 | request.onreadystatechange = (e) => { 23 | if (request.readyState !== 4) { 24 | return; 25 | } 26 | 27 | if (request.status === 200) { 28 | successCallback(JSON.parse(request.responseText)) 29 | 30 | } else { 31 | // console.warn('error'); 32 | } 33 | }; 34 | 35 | request.open('GET',url); 36 | request.send(); 37 | }, 38 | } 39 | 40 | export default Util; 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/containers/detail.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/29. 3 | */ 4 | /** 5 | * Sample React Native App 6 | * https://github.com/facebook/react-native 7 | * @flow 8 | */ 9 | 10 | import React, { Component } from 'react'; 11 | import { 12 | AppRegistry, 13 | StyleSheet, 14 | Text, 15 | View, 16 | Dimensions, 17 | Image, 18 | TouchableOpacity 19 | } from 'react-native'; 20 | 21 | // import x from './信息页_选择_icon.png' 22 | 23 | var {width, height} = Dimensions.get('window'); 24 | 25 | 26 | export default class detail extends Component { 27 | 28 | pushDetail(tag){ 29 | switch (tag) { 30 | case ('关于我们'): 31 | return (alert('关于我们')); 32 | case ('当前版本'): 33 | return (alert('当前版本')); 34 | case ('喜欢我们吗?去打分吧!'): 35 | return (alert('喜欢我们吗?去打分吧!')); 36 | case ('动力基金'): 37 | return (alert('动力基金')); 38 | case ('运动记录'): 39 | return (alert('运动记录')); 40 | case ('头像'): 41 | return (alert('头像')); 42 | default: 43 | return(alert('什么鬼!')); 44 | } 45 | } 46 | 47 | bottomView(){ 48 | return( 49 | 50 | this.pushDetail('关于我们')} 55 | /> 56 | this.pushDetail('当前版本')} 62 | /> 63 | this.pushDetail('喜欢我们吗?去打分吧!')} 68 | /> 69 | 70 | ) 71 | } 72 | 73 | middleView(){ 74 | return( 75 | 76 | this.pushDetail('动力基金')} 82 | /> 83 | this.pushDetail('运动记录')} 88 | /> 89 | 90 | ) 91 | } 92 | 93 | headerView(){ 94 | return( 95 | this.pushDetail('头像')}> 96 | 97 | 98 | 西西 99 | 100 | 101 | 102 | ) 103 | } 104 | navigatorView(){ 105 | return( 106 | 107 | 信息 108 | 109 | ) 110 | } 111 | render() { 112 | return ( 113 | 114 | {this.navigatorView()} 115 | {this.headerView()} 116 | {this.middleView()} 117 | {this.bottomView()} 118 | 119 | ); 120 | } 121 | } 122 | 123 | class Item extends Component{ 124 | 125 | static defaultProps = { 126 | itemImage:React.PropTypes.string.isRequired, 127 | itemText:React.PropTypes.string.isRequired, 128 | itemRightText:React.PropTypes.string.isRequired, 129 | isRightText:React.PropTypes.bool, 130 | isLineHidden:React.PropTypes.bool, 131 | isArrow:React.PropTypes.bool, 132 | itemPress:React.PropTypes.func, 133 | }; 134 | render(){ 135 | return( 136 | this.props.itemPress()}> 137 | 138 | 139 | {this.props.itemText} 140 | {this.props.isRightText? 141 | {this.props.itemRightText} 142 | :null 143 | } 144 | {this.props.isArrow ? 145 | 146 | : 147 | V1.0 148 | } 149 | 150 | {this.props.isLineHidden? 151 | 152 | :null 153 | } 154 | 155 | 156 | ) 157 | } 158 | } 159 | 160 | const styles = StyleSheet.create({ 161 | container: { 162 | flex: 1, 163 | backgroundColor: '#f7f7f7', 164 | }, 165 | navigatorViewStyle: { 166 | backgroundColor:'#fff', 167 | width:width, 168 | height:64 169 | }, 170 | navigatorTextStyle: { 171 | justifyContent:'center', 172 | alignSelf:'center', 173 | fontSize:18, 174 | color:'#000', 175 | marginTop:33 176 | }, 177 | headerViewStyle:{ 178 | flexDirection:'row', 179 | height:74, 180 | width:width, 181 | backgroundColor:'#fff', 182 | marginTop:10, 183 | }, 184 | headerImageStyle: { 185 | height:40, 186 | width:40, 187 | marginLeft:20, 188 | backgroundColor:'red', 189 | alignSelf:'center' 190 | }, 191 | headerTextStyle:{ 192 | marginLeft:20, 193 | alignSelf:'center', 194 | color:'#172434', 195 | fontFamily:'PingFangSC-Regular', 196 | fontSize:16, 197 | }, 198 | headerRightImageStyle: { 199 | alignSelf:'center', 200 | // backgroundColor:'red', 201 | height:12, 202 | width:7, 203 | position:'absolute', 204 | right:20.5, 205 | top:30.5 206 | }, 207 | itemViewStyle: { 208 | height:60, 209 | width:width, 210 | backgroundColor:'#fff', 211 | flexDirection:'row', 212 | }, 213 | itemLeftImageStyle: { 214 | width:20, 215 | height:20, 216 | marginLeft:20, 217 | alignSelf:'center', 218 | backgroundColor:'red' 219 | }, 220 | itemTextStyle: { 221 | marginLeft:12, 222 | color:'#000', 223 | fontSize:16, 224 | fontFamily:'PingFangSC-Regular', 225 | alignSelf:'center', 226 | }, 227 | itemRightTextStyle :{ 228 | color:'#f30d31', 229 | fontSize:13, 230 | fontFamily:'PingFangSC-Regular', 231 | alignSelf:'center', 232 | position:'absolute', 233 | right:40, 234 | top:21, 235 | }, 236 | itemRightImageStyle:{ 237 | alignSelf:'center', 238 | // backgroundColor:'red', 239 | height:12, 240 | width:7, 241 | position:'absolute', 242 | right:20.5, 243 | top:24 244 | }, 245 | lineStyle:{ 246 | height:1, 247 | width:width, 248 | backgroundColor:'#E5E5E5', 249 | position:'absolute', 250 | left:20, 251 | bottom:1, 252 | }, 253 | versionStyle: { 254 | position:'absolute', 255 | right:20, 256 | top:18.5, 257 | fontSize:16, 258 | color:'#999' 259 | } 260 | 261 | }); 262 | 263 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/containers/homeContainer.js: -------------------------------------------------------------------------------- 1 | 2 | 3 | import React, { Component } from 'react'; 4 | import {connect} from 'react-redux'; 5 | import Home from '../pages/Home'; 6 | 7 | class HomeContainer extends Component { 8 | render(){ 9 | return( 10 | 11 | ) 12 | } 13 | } 14 | 15 | export default connect((state) => { 16 | const {Home} = state; 17 | return{ 18 | Home 19 | } 20 | }) 21 | (HomeContainer); -------------------------------------------------------------------------------- /Example/App/Page/SixPage/containers/mainContainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | export default class mainContainer extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.android.js 24 | 25 | 26 | Double tap R on your keyboard to reload,{'\n'} 27 | Shake or press menu button for dev menu 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | 35 | const styles = StyleSheet.create({ 36 | container: { 37 | flex: 1, 38 | justifyContent: 'center', 39 | alignItems: 'center', 40 | backgroundColor: '#F5FCFF', 41 | }, 42 | welcome: { 43 | fontSize: 20, 44 | textAlign: 'center', 45 | margin: 10, 46 | }, 47 | instructions: { 48 | textAlign: 'center', 49 | color: '#333333', 50 | marginBottom: 5, 51 | }, 52 | }); 53 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/containers/信息页_选择_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/SixPage/containers/信息页_选择_icon.png -------------------------------------------------------------------------------- /Example/App/Page/SixPage/pages/Home.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | */ 5 | 6 | import React, { Component } from 'react'; 7 | import { 8 | StyleSheet, 9 | Text, 10 | ScrollView, 11 | Image, 12 | ListView, 13 | TouchableOpacity, 14 | View, 15 | InteractionManager, 16 | RefreshControl, 17 | Navigator, 18 | } from 'react-native'; 19 | 20 | import { home, } from '../actions/homeAction'; 21 | 22 | import Common from '../common/common'; 23 | import Loading from '../common/Loading'; 24 | import LoadMoreFooter from '../common/LoadMoreFooter'; 25 | import HeaderView from '../common/HeaderView'; 26 | import HomeDetial from './HomeDetial'; 27 | 28 | let limit = 21; 29 | let offest = ''; 30 | let tag = ''; 31 | let isLoadMore = false; 32 | let isRefreshing = false; 33 | let isLoading = true; 34 | class Home extends Component { 35 | 36 | constructor(props) { 37 | super(props); //这一句不能省略,照抄即可 38 | // debugger 39 | this._renderRow = this._renderRow.bind(this); 40 | this.state = { 41 | dataSource: new ListView.DataSource({ 42 | rowHasChanged: (row1, row2) => row1 !== row2, 43 | }), 44 | }; 45 | } 46 | 47 | componentDidMount() { 48 | InteractionManager.runAfterInteractions(() => { 49 | const {dispatch} = this.props; 50 | dispatch(home(tag, offest, limit, isLoadMore, isRefreshing, isLoading)); 51 | }) 52 | } 53 | 54 | render() { 55 | const { Home,rowDate } = this.props; 56 | tag = rowDate; 57 | // console.log(this.props); 58 | // debugger 59 | let homeList = Home.HomeList; 60 | let titleName = '最新'; 61 | return ( 62 | 63 | 67 | {Home.isLoading ? : 68 | 87 | } 88 | /> 89 | } 90 | 91 | 92 | ); 93 | 94 | } 95 | 96 | 97 | 98 | _renderRow(rowDate) { 99 | // console.log('http://img.hb.aicdn.com/' + rowDate.file.key + '_fw236'); 100 | 101 | return ( 102 | 103 | 107 | 111 | 112 | 113 | ); 114 | } 115 | 116 | _onPressFeedItem(rowDate) { 117 | InteractionManager.runAfterInteractions(() => { 118 | this.props.navigator.push({ 119 | name: 'HomeDetial', 120 | component: HomeDetial, 121 | sceneConfig: Navigator.SceneConfigs.FloatFromBottom, 122 | passProps: { 123 | rowDate: rowDate, 124 | } 125 | }) 126 | }); 127 | } 128 | _renderFooter() { 129 | const {Home} = this.props; 130 | if (Home.isLoadMore) { 131 | return 132 | } 133 | } 134 | 135 | _onScroll() { 136 | if (!isLoadMore) isLoadMore = true; 137 | } 138 | 139 | // 下拉刷新 140 | _onRefresh() { 141 | if (isLoadMore) { 142 | const {dispatch, Home} = this.props; 143 | isLoadMore = false; 144 | isRefreshing = true; 145 | dispatch(home('', '', limit, isLoadMore, isRefreshing, isLoading)); 146 | 147 | 148 | } 149 | } 150 | 151 | // 上拉加载 152 | _onEndReach() { 153 | 154 | InteractionManager.runAfterInteractions(() => { 155 | const {dispatch, Home} = this.props; 156 | let homeList = Home.HomeList; 157 | isLoadMore = true; 158 | isLoading = false; 159 | offest = homeList[homeList.length - 1].seq 160 | dispatch(home(tag, offest, limit, isLoadMore, isRefreshing, isLoading)); 161 | }) 162 | 163 | } 164 | 165 | } 166 | 167 | 168 | const styles = StyleSheet.create({ 169 | container: { 170 | width: Common.window.width / 3, 171 | height: Common.window.width / 2, 172 | justifyContent: 'center', 173 | alignItems: 'center', 174 | backgroundColor: '#F5FCFF', 175 | }, 176 | listView: { 177 | backgroundColor: '#F5FCFF', 178 | height: Common.window.height - 44 - 60 - 20, 179 | }, 180 | thumbnail: { 181 | width: Common.window.width / 3 - 10, 182 | height: Common.window.width / 2 - 10, 183 | 184 | }, 185 | list: { 186 | justifyContent: 'center', 187 | flexDirection: 'row', 188 | flexWrap: 'wrap', 189 | alignItems: 'center', 190 | 191 | }, 192 | header: { 193 | marginTop: 20, 194 | height: 44, 195 | alignItems: 'center', 196 | justifyContent: 'center', 197 | flexDirection: 'row', 198 | backgroundColor: 'white', 199 | }, 200 | title: { 201 | color: 'black', 202 | }, 203 | }); 204 | 205 | module.exports = Home; -------------------------------------------------------------------------------- /Example/App/Page/SixPage/pages/HomeDetial.js: -------------------------------------------------------------------------------- 1 | import React, { 2 | Component 3 | } from 'react'; 4 | import { 5 | StyleSheet, 6 | Text, 7 | Image, 8 | View, 9 | } from 'react-native'; 10 | import Common from '../common/common'; 11 | 12 | export default class HomeDetil extends Component { 13 | render() { 14 | const {rowDate} = this.props 15 | 16 | return ( 17 | 18 | 22 | 23 | ); 24 | } 25 | } 26 | const styles = StyleSheet.create({ 27 | thumbnail: { 28 | width: Common.window.width, 29 | height: Common.window.height, 30 | 31 | }, 32 | }) 33 | 34 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/reducers/homeReducer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/30. 3 | */ 4 | import * as types from '../actions/actionTypes'; 5 | 6 | const initialState = { 7 | HomeList: [], 8 | isLoading: true, 9 | isLoadMore: false, 10 | isRefreshing: false, 11 | }; 12 | 13 | 14 | let homeReducer = (state = initialState , action) => { 15 | switch (action.type){ 16 | case types.FETCH_HOME_LIST: 17 | return Object.assign({},state , { 18 | isLoading:action.isLoading, 19 | isRefreshing:action.isRefreshing, 20 | isLoadMore:action.isLoadingMore 21 | }); 22 | case types.RECEIVE_HOME_LIST: 23 | return Object.assign({} , state, { 24 | HomeList: state.isLoadMore ? state.HomeList.concat(action.homeList) : action.homeList, 25 | isRefreshing:false, 26 | isLoading:false, 27 | }); 28 | default: 29 | return state; 30 | } 31 | }; 32 | 33 | export default homeReducer; 34 | 35 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/reducers/rootReducer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/30. 3 | */ 4 | import { combineReducers } from 'redux' 5 | import Home from './homeReducer'; 6 | 7 | 8 | export default rootReducer = combineReducers({ 9 | Home, 10 | }) 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /Example/App/Page/SixPage/resource/main-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/SixPage/resource/main-normal.png -------------------------------------------------------------------------------- /Example/App/Page/SixPage/resource/main-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/SixPage/resource/main-selected.png -------------------------------------------------------------------------------- /Example/App/Page/SixPage/resource/news-normal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/SixPage/resource/news-normal.png -------------------------------------------------------------------------------- /Example/App/Page/SixPage/resource/news-selected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/App/Page/SixPage/resource/news-selected.png -------------------------------------------------------------------------------- /Example/App/Page/SixPage/store/store.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/30. 3 | */ 4 | import {createStore , applyMiddleware} from 'redux'; 5 | import thunk from 'redux-thunk'; 6 | import rootReducer from '../reducers/rootReducer'; 7 | let createStoreWithMiddleware = applyMiddleware(thunk)(createStore); 8 | let store = createStoreWithMiddleware(rootReducer); 9 | // let state = store.getState(); 10 | // alert(state.Search.searchText) 11 | export default store; 12 | 13 | -------------------------------------------------------------------------------- /Example/App/Page/ThreePage/PushButton.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/17. 3 | */ 4 | import React, { Component, PropTypes } from 'react'; 5 | import { 6 | requireNativeComponent 7 | } from 'react-native'; 8 | 9 | var PushManager = requireNativeComponent('RCTPushView', PushView); 10 | 11 | 12 | export default class PushView extends Component { 13 | 14 | static propTypes = { 15 | /** 16 | * 17 | * 定义组件需要传到原生端的属性 18 | * 使用React.PropTypes来进行校验 19 | */ 20 | //Button的title 21 | btnTitle:PropTypes.string, 22 | //按钮点击事件 23 | onButtonClicked:PropTypes.func, 24 | 25 | }; 26 | 27 | render() { 28 | return ( 29 | 30 | ); 31 | } 32 | } -------------------------------------------------------------------------------- /Example/App/Page/ThreePage/Three.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/11/7. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | TouchableOpacity, 11 | NativeModules 12 | } from 'react-native'; 13 | 14 | import PushButton from './PushButton'; 15 | 16 | class PageOne extends Component { 17 | 18 | render() { 19 | 20 | return( 21 | 22 | 这是页面一! 23 | 24 | ); 25 | } 26 | } 27 | 28 | export default class Three extends Component { 29 | 30 | // 组件要不要更新 31 | shouldComponentUpdate() { 32 | return true; 33 | } 34 | // 组件将要更新 35 | componentWillUpdate(){ 36 | 37 | } 38 | 39 | // 组件已经更新 40 | componentDidUpdate() { 41 | 42 | } 43 | 44 | // 组件将要加载 45 | componentWillMount() { 46 | 47 | } 48 | 49 | // 在调用render之后,组件已经加载 50 | componentDidMount() { 51 | 52 | } 53 | 54 | // 组件加载 55 | render() { 56 | // var { launchOptions } = this.props; 57 | // if (launchOptions && launchOptions.componentName) { 58 | // switch (launchOptions.componentName) { 59 | // case 'PageOne': 60 | // return( 61 | // 62 | // ); 63 | // break; 64 | // default: 65 | // 66 | // } 67 | // } 68 | return ( 69 | 70 | 71 | 72 | { 76 | console.log('React事件' + event.nativeEvent.randomValue); 77 | alert('原生点击事件' + event.nativeEvent.randomValue) 78 | }} 79 | /> 80 | 81 | 82 | ); 83 | } 84 | } 85 | 86 | const styles = StyleSheet.create({ 87 | container: { 88 | flex: 1, 89 | }, 90 | buttonStyle:{ 91 | width:200, 92 | height:100, 93 | backgroundColor:'red', 94 | alignSelf:'center', 95 | justifyContent: 'center', 96 | marginTop:100 97 | } 98 | }); 99 | 100 | AppRegistry.registerComponent('Three', () => Three); -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/Account/Account.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/13. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | AsyncStorage, 11 | Image, 12 | TouchableOpacity, 13 | Dimensions 14 | } from 'react-native'; 15 | var {width, height} = Dimensions.get('window'); 16 | var Platform = require('react-native').Platform; 17 | // var ImagePicker = require('react-native-image-picker'); 18 | import ImagePicker from 'react-native-image-picker'; 19 | import NavBar from 'react-native-navbar'; 20 | import Login from './Login' 21 | import Icon from 'react-native-vector-icons/Ionicons'; 22 | 23 | // 调取相册需要 24 | var options = { 25 | title: 'Select Avatar', 26 | customButtons: [ 27 | {name: 'fb', title: 'Choose Photo from Facebook'}, 28 | ], 29 | storageOptions: { 30 | skipBackup: true, 31 | path: 'images' 32 | } 33 | }; 34 | export default class Account extends Component { 35 | constructor(props){ 36 | super(props); 37 | this.state = { 38 | isLogin:false, // 是否登录 39 | user:null, // 用户信息 40 | }; 41 | // 获取用户状态 42 | this.asynGetAppStatus = this.asynGetAppStatus.bind(this); 43 | // 打开相册 44 | this.pickPhoto = this.pickPhoto.bind(this); 45 | } 46 | 47 | pickPhoto(){ 48 | ImagePicker.showImagePicker(options, (response) => { 49 | console.log('Response = ', response); 50 | 51 | if (response.didCancel) { 52 | console.log('User cancelled image picker'); 53 | } 54 | else if (response.error) { 55 | console.log('ImagePicker Error: ', response.error); 56 | } 57 | else if (response.customButton) { 58 | console.log('User tapped custom button: ', response.customButton); 59 | } 60 | else { 61 | let user = this.state.user; 62 | let avatarUrl = ''; 63 | // You can display the image using either data... 64 | const source = {uri: 'data:image/jpeg;base64,' + response.data, isStatic: true}; 65 | // 得到URL,这个不分平台, 第一种方案 66 | // avatarUrl = 'data:image/jpeg;base64,' + response.data; 67 | 68 | // 下面是分平台的, 第二种方案 69 | // or a reference to the platform specific asset location 70 | if (Platform.OS === 'ios') { 71 | const source = {uri: response.uri.replace('file://', ''), isStatic: true}; 72 | avatarUrl = response.uri.replace('file://', ''); 73 | } else { 74 | const source = {uri: response.uri, isStatic: true}; 75 | avatarUrl = response.uri; 76 | } 77 | 78 | user.avatar = avatarUrl; 79 | 80 | this.setState({ 81 | user:user 82 | }); 83 | } 84 | }); 85 | } 86 | 87 | asynGetAppStatus(){ 88 | AsyncStorage.getItem('user') 89 | .then((data)=>{ 90 | let user; 91 | let newState = {}; 92 | if(data){ 93 | user = JSON.parse(data); 94 | console.log(data); 95 | } 96 | // 判断user是否存在 97 | if (user && user.accessToken){ 98 | newState.isLogin = true; 99 | newState.user = user; 100 | }else { 101 | newState.isLogin = false; 102 | } 103 | this.setState(newState); 104 | }) 105 | .catch((error)=>{ 106 | alert(error) 107 | }); 108 | } 109 | 110 | componentDidMount() { 111 | this.asynGetAppStatus(); 112 | } 113 | 114 | render() { 115 | let user = this.state.user; 116 | if (!user){ 117 | return 118 | } 119 | var titleConfig = { 120 | title: '我的', 121 | style: {color:'black',fontSize:20,fontWeight:'600'} 122 | }; 123 | return ( 124 | 125 | 129 | {/*如果有用户的头像则显示用户的头像,如果没有则添加用户头像的图标*/} 130 | {user.avatar ? 131 | 135 | 139 | {/*用户真正的头像*/} 140 | 142 | 145 | 146 | 147 | 点击这里可以更换头像 148 | 149 | 150 | : 151 | 152 | 添加用户头像 153 | 155 | 160 | 161 | 162 | } 163 | 164 | 165 | 166 | 167 | ); 168 | } 169 | 170 | } 171 | 172 | const styles = StyleSheet.create({ 173 | container:{ 174 | flex:1, 175 | }, 176 | // 加载头像的外层View 177 | avatarContainer:{ 178 | width:width, 179 | height:140, 180 | justifyContent:'center', 181 | alignItems:'center', 182 | backgroundColor:'#666' 183 | }, 184 | // 加载头像的提示文字 185 | avatarTextStyle:{ 186 | fontSize:16, 187 | fontWeight:'600', 188 | textAlign:'center', 189 | color:'#fff', 190 | backgroundColor:'transparent' 191 | }, 192 | // 点击按钮 193 | avatarBtnStyle:{ 194 | marginTop:15, 195 | justifyContent:'center', 196 | alignItems:'center' 197 | }, 198 | // 添加头像按钮 199 | avatarIconStyle:{ 200 | padding:20, 201 | paddingLeft:25, 202 | paddingRight:25, 203 | color:'#666', 204 | backgroundColor:'#fff', 205 | borderRadius:30 206 | }, 207 | // 用户之前的头像的外层View 208 | avatarViewStyle:{ 209 | marginTop:15, 210 | justifyContent:'center', 211 | alignItems:'center' 212 | }, 213 | // 用户之前的头像 214 | avatarStyle:{ 215 | width:width*0.2, 216 | height:width*0.2, 217 | marginBottom:20, 218 | borderRadius:width*0.1, 219 | borderWidth:1, 220 | borderColor:'red', 221 | resizeMode:'cover' 222 | } 223 | }); 224 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/Common/config.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/14. 3 | */ 4 | 'use strict' 5 | 6 | const config = { 7 | api:{ 8 | base:'http://rap.taobao.org/mockjsdata/8647/', 9 | list:'api/list', 10 | handle:'api/handle', 11 | comments:'api/comments',//评论数量 12 | comment:'api/comment', // 13 | signup:'api/user/signup',//发送验证码 14 | verify:'api/user/verify',// 登录验证 15 | }, 16 | map:{ 17 | method:'POST', 18 | header:{ 19 | 'Accept-Encoding':'gzip, deflate', 20 | 'Content-Type':'application/json', 21 | 'User-Agent':'11', 22 | 'X-Device-ID':'111', 23 | 'X-Ip':'111', 24 | 25 | }, 26 | // body:JSON.stringify(body), 27 | follow:20, 28 | timeout:8000, 29 | size:0 30 | }, 31 | 32 | }; 33 | 34 | module.exports = config; 35 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/Common/request.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/14. 3 | */ 4 | 'use strict' 5 | 6 | import Mock from 'mockjs'; 7 | import config from './config'; 8 | import queryString from 'query-string' 9 | import _ from 'lodash'; 10 | let request = { 11 | 12 | } 13 | 14 | // 设定params json对象 15 | request.get = (url,params) => { 16 | if(params){ 17 | url += '?' + queryString.stringify(params) 18 | } 19 | 20 | return fetch(url) 21 | .then((response) => response.json()) 22 | .then((response) => Mock.mock(response)) 23 | }; 24 | 25 | request.post = (url,body) => { 26 | 27 | // json对象的合并 工具:loadsh 28 | // config.map 合并 body 29 | let map = _.extend(config.map,{ 30 | body : JSON.stringify(body) 31 | }); 32 | 33 | 34 | return fetch(url,map) 35 | .then((response) => response.json()) 36 | .then((response) => Mock.mock(response)) 37 | 38 | }; 39 | 40 | module.exports = request; 41 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/Edit/Edit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/13. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View 10 | } from 'react-native'; 11 | 12 | export default class Edit extends Component { 13 | render() { 14 | return ( 15 | 16 | 17 | Edit 18 | 19 | 20 | ); 21 | } 22 | } 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | flex: 1, 27 | justifyContent: 'center', 28 | alignItems: 'center', 29 | backgroundColor: '#F5FCFF', 30 | }, 31 | welcome: { 32 | fontSize: 20, 33 | textAlign: 'center', 34 | margin: 10, 35 | }, 36 | }); 37 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/List/List.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/13. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | ListView, 11 | Image, 12 | TouchableHighlight, 13 | Dimensions, 14 | ActivityIndicator, 15 | RefreshControl, 16 | InteractionManager 17 | } from 'react-native'; 18 | 19 | var {width, height} = Dimensions.get('window'); 20 | 21 | let cacheResults = { 22 | nextPage:1, 23 | items:[], 24 | total:0, 25 | }; 26 | 27 | import NavBar from 'react-native-navbar'; 28 | import Icon from 'react-native-vector-icons/Ionicons'; 29 | import Item from './item' 30 | import config from '../Common/config'; 31 | import request from '../Common/request'; 32 | import Detail from './Detail'; 33 | 34 | export default class List extends Component { 35 | constructor(props){ 36 | super(props); 37 | var ds = new ListView.DataSource({rowHasChanged:(r1,r2) => r1 !== r2}); 38 | this.state = { 39 | dataSource : ds, 40 | isLoadingMore:false, 41 | isRefreshing:false 42 | }; 43 | }; 44 | 45 | componentDidMount() { 46 | this.loadData(1); 47 | } 48 | 49 | loadData(page) { 50 | console.log("page:" + page); 51 | if (page !== 0){ 52 | this.setState({ 53 | isLoadingMore:true 54 | }); 55 | }else { 56 | this.setState({ 57 | isRefreshing :true 58 | }); 59 | } 60 | // 第一步,完整地址 61 | request.get(config.api.base + config.api.list,{ 62 | accessToken:'111', 63 | page:page 64 | }).then( 65 | (data) => { 66 | console.log(data); 67 | if (data.success){ 68 | //把服务器得到的数据,存到里面 69 | let items = cacheResults.items.slice(); 70 | 71 | if (page !== 0){ 72 | // concat 需要看一下 73 | items = items.concat(data.data); 74 | 75 | cacheResults.nextPage += 1; 76 | } else { 77 | items = data.data.concat(items); 78 | } 79 | cacheResults.items = items; 80 | cacheResults.total = data.total; 81 | 82 | console.log('总数据的长度' + cacheResults.total); 83 | console.log('当前的listView数据长度' + cacheResults.items.length); 84 | setTimeout(()=>{ 85 | if (page !== 0){ 86 | this.setState({ 87 | dataSource: this.state.dataSource.cloneWithRows(cacheResults.items), 88 | isLoadingMore:false 89 | }); 90 | } else { 91 | this.setState({ 92 | dataSource: this.state.dataSource.cloneWithRows(cacheResults.items), 93 | isRefreshing :false 94 | }); 95 | } 96 | },0); 97 | } 98 | } 99 | ).catch( 100 | (err)=>{ 101 | if (page !== 0){ 102 | this.setState({ 103 | isLoadingMore:false 104 | }); 105 | }else { 106 | this.setState({ 107 | isRefreshing:false 108 | }); 109 | } 110 | alert('error' + err); 111 | } 112 | ); 113 | } 114 | 115 | // 上拉加载更多数据 116 | loadMoreData=()=>{ 117 | // 判断有没有更多数据 或者 数据正在加载 118 | // 这样的时候需要return 119 | if (!this.isMore() || this.state.isLoadingMore){ 120 | return; 121 | } 122 | 123 | // 去服务器请求加载更多数据 124 | let page = cacheResults.nextPage; 125 | this.loadData(page); 126 | }; 127 | 128 | // 服务器有没有更多数据 129 | isMore(){ 130 | // 只要列表长度和total数据比较不相等,那就说明有数据 131 | return cacheResults.items.length !== cacheResults.total 132 | } 133 | 134 | // 下拉刷新 135 | _onRefresh=()=>{ 136 | if(!this.isMore() || this.state.isRefreshing){ 137 | console.log(this.state.isRefreshing); 138 | return; 139 | } 140 | 141 | // 去服务器获取数据 142 | // page 相当于数据的页码 143 | this.loadData(0); 144 | }; 145 | 146 | render() { 147 | var titleConfig = { 148 | title: '视频', 149 | style: {color:'black',fontSize:20,fontWeight:'600'} 150 | }; 151 | return ( 152 | 153 | 157 | this.renderRow(rowData)} 160 | style={styles.listStyle} 161 | enableEmptySections={true} 162 | onEndReachedThreshold={20} 163 | onEndReached={this.loadMoreData} 164 | renderFooter={this.renderFooter} 165 | refreshControl={ 166 | 170 | } 171 | /> 172 | 173 | ); 174 | } 175 | 176 | // 返回底部信息 177 | renderFooter=()=>{ 178 | if (!this.isMore() && cacheResults.total !== 0 ){ 179 | return ( 180 | 181 | 没有更多数据了 182 | 183 | ) 184 | } 185 | 186 | if (!this.state.isLoadingMore){ 187 | return 188 | } 189 | 190 | return( 191 | 194 | ) 195 | }; 196 | 197 | renderRow(rowData){ 198 | return( 199 | this.pushPage(rowData)} 202 | key={rowData._id} 203 | /> 204 | ) 205 | } 206 | 207 | pushPage(rowData) { 208 | let {navigator} = this.props; 209 | if (navigator) { 210 | // 解构 和 模式匹配 211 | InteractionManager.runAfterInteractions(()=> { 212 | navigator.push({ 213 | title: 'Detail', 214 | component: Detail, 215 | passProps:{ 216 | rowData:rowData 217 | } 218 | }) 219 | }); 220 | } 221 | } 222 | } 223 | 224 | const styles = StyleSheet.create({ 225 | container: { 226 | flex: 1, 227 | backgroundColor: '#F5FCFF', 228 | }, 229 | welcome: { 230 | fontSize: 20, 231 | textAlign: 'center', 232 | margin: 10, 233 | }, 234 | listStyle: { 235 | backgroundColor:'white' 236 | }, 237 | 238 | 239 | 240 | 241 | loadMoreStyle:{ 242 | marginVertical:20 243 | }, 244 | loadMoreTextStyle:{ 245 | fontSize:18, 246 | color:'#777', 247 | alignItems :'center' 248 | }, 249 | }); -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/List/VideoPlayerAndroid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/17. 3 | */ 4 | import React, { 5 | Component 6 | } from 'react'; 7 | 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | TouchableOpacity, 13 | View, 14 | } from 'react-native'; 15 | 16 | import Video from 'react-native-video'; 17 | 18 | export default class VideoPlayer extends Component { 19 | constructor(props) { 20 | super(props); 21 | this.onLoad = this.onLoad.bind(this); 22 | this.onProgress = this.onProgress.bind(this); 23 | } 24 | 25 | state = { 26 | rate: 1, 27 | volume: 1, 28 | muted: false, 29 | resizeMode: 'contain', 30 | duration: 0.0, 31 | currentTime: 0.0, 32 | }; 33 | 34 | onLoad(data) { 35 | this.setState({duration: data.duration}); 36 | } 37 | 38 | onProgress(data) { 39 | this.setState({currentTime: data.currentTime}); 40 | } 41 | 42 | getCurrentTimePercentage() { 43 | if (this.state.currentTime > 0) { 44 | return parseFloat(this.state.currentTime) / parseFloat(this.state.duration); 45 | } else { 46 | return 0; 47 | } 48 | } 49 | 50 | renderRateControl(rate) { 51 | const isSelected = (this.state.rate == rate); 52 | 53 | return ( 54 | { this.setState({rate: rate}) }}> 55 | 56 | {rate}x 57 | 58 | 59 | ) 60 | } 61 | 62 | renderResizeModeControl(resizeMode) { 63 | const isSelected = (this.state.resizeMode == resizeMode); 64 | 65 | return ( 66 | { this.setState({resizeMode: resizeMode}) }}> 67 | 68 | {resizeMode} 69 | 70 | 71 | ) 72 | } 73 | 74 | renderVolumeControl(volume) { 75 | const isSelected = (this.state.volume == volume); 76 | 77 | return ( 78 | { this.setState({volume: volume}) }}> 79 | 80 | {volume * 100}% 81 | 82 | 83 | ) 84 | } 85 | 86 | render() { 87 | const flexCompleted = this.getCurrentTimePercentage() * 100; 88 | const flexRemaining = (1 - this.getCurrentTimePercentage()) * 100; 89 | 90 | return ( 91 | 92 | {this.setState({paused: !this.state.paused})}}> 93 | 105 | 106 | 107 | 108 | 109 | {this.renderRateControl(0.25)} 110 | {this.renderRateControl(0.5)} 111 | {this.renderRateControl(1.0)} 112 | {this.renderRateControl(1.5)} 113 | {this.renderRateControl(2.0)} 114 | 115 | 116 | 117 | {this.renderVolumeControl(0.5)} 118 | {this.renderVolumeControl(1)} 119 | {this.renderVolumeControl(1.5)} 120 | 121 | 122 | 123 | {this.renderResizeModeControl('cover')} 124 | {this.renderResizeModeControl('contain')} 125 | {this.renderResizeModeControl('stretch')} 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | ); 138 | } 139 | } 140 | 141 | 142 | const styles = StyleSheet.create({ 143 | container: { 144 | flex: 1, 145 | justifyContent: 'center', 146 | alignItems: 'center', 147 | backgroundColor: 'black', 148 | }, 149 | fullScreen: { 150 | position: 'absolute', 151 | top: 0, 152 | left: 0, 153 | bottom: 0, 154 | right: 0, 155 | }, 156 | controls: { 157 | backgroundColor: "transparent", 158 | borderRadius: 5, 159 | position: 'absolute', 160 | bottom: 20, 161 | left: 20, 162 | right: 20, 163 | }, 164 | progress: { 165 | flex: 1, 166 | flexDirection: 'row', 167 | borderRadius: 3, 168 | overflow: 'hidden', 169 | }, 170 | innerProgressCompleted: { 171 | height: 20, 172 | backgroundColor: '#cccccc', 173 | }, 174 | innerProgressRemaining: { 175 | height: 20, 176 | backgroundColor: '#2C2C2C', 177 | }, 178 | generalControls: { 179 | flex: 1, 180 | flexDirection: 'row', 181 | borderRadius: 4, 182 | overflow: 'hidden', 183 | paddingBottom: 10, 184 | }, 185 | rateControl: { 186 | flex: 1, 187 | flexDirection: 'row', 188 | justifyContent: 'center', 189 | }, 190 | volumeControl: { 191 | flex: 1, 192 | flexDirection: 'row', 193 | justifyContent: 'center', 194 | }, 195 | resizeModeControl: { 196 | flex: 1, 197 | flexDirection: 'row', 198 | alignItems: 'center', 199 | justifyContent: 'center', 200 | }, 201 | controlOption: { 202 | alignSelf: 'center', 203 | fontSize: 11, 204 | color: "white", 205 | paddingLeft: 2, 206 | paddingRight: 2, 207 | lineHeight: 12, 208 | }, 209 | }); -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/List/item.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/17. 3 | */ 4 | 5 | import React, { Component } from 'react'; 6 | import { 7 | AppRegistry, 8 | StyleSheet, 9 | Text, 10 | View, 11 | TouchableHighlight, 12 | Image, 13 | Dimensions, 14 | 15 | } from 'react-native'; 16 | 17 | var {width, height} = Dimensions.get('window'); 18 | import Icon from 'react-native-vector-icons/Ionicons'; 19 | import Request from '../Common/request'; 20 | import Config from '../Common/config'; 21 | 22 | export default class Item extends Component { 23 | constructor(props){ 24 | super(props); 25 | this.state = { 26 | rowData:this.props.rowData, 27 | isHandle:this.props.rowData.isHandle 28 | }; 29 | } 30 | 31 | handleClick=()=>{ 32 | let isHandle = !this.state.isHandle; 33 | let rowData = this.state.rowData; 34 | let url = Config.api.base + Config.api.handle; 35 | let body = { 36 | id:rowData.id, 37 | isHandle: isHandle ? 'yes' : 'no', 38 | accessToken:'rabbit' 39 | }; 40 | Request.post(url,body) 41 | .then( 42 | (data)=>{ 43 | console.log(data); 44 | if (data && data.success){ 45 | this.setState({ 46 | isHandle:isHandle 47 | }); 48 | }else { 49 | (alert('网络错误,请稍后重试!')); 50 | } 51 | } 52 | ) 53 | .catch( 54 | (error)=>{ 55 | (alert('网络错误,请稍后重试:'+error)); 56 | } 57 | ); 58 | }; 59 | 60 | render() { 61 | let rowData = this.state.rowData; 62 | return ( 63 | 65 | 66 | {rowData.title} 67 | 68 | 73 | 74 | 75 | 76 | 82 | 点赞 83 | 84 | 85 | 90 | 评论 91 | 92 | 93 | 94 | 95 | ); 96 | } 97 | } 98 | 99 | const styles = StyleSheet.create({ 100 | itemStyle:{ 101 | width:width, 102 | marginBottom:10, 103 | backgroundColor:'white' 104 | }, 105 | titleStyle:{ 106 | fontSize:18, 107 | padding:3, 108 | color:'#333', 109 | }, 110 | imageStyle:{ 111 | height:width*0.56, 112 | width:width, 113 | resizeMode:'cover' 114 | }, 115 | itemFootStyle:{ 116 | flexDirection:'row', 117 | justifyContent:'space-between', 118 | backgroundColor:'#eee' 119 | // width:width, 120 | }, 121 | handleBox:{ 122 | padding:10, 123 | flexDirection:'row', 124 | width:width/2-0.5, 125 | justifyContent:'center', 126 | backgroundColor:'white' 127 | }, 128 | handleImageStyle:{ 129 | fontSize:22, 130 | // color:"#333" 131 | color:"#ed7b66" 132 | }, 133 | handleSelectedStyle:{ 134 | fontSize:22, 135 | color:"#333" 136 | }, 137 | handleText:{ 138 | fontSize:18, 139 | color:"#333", 140 | paddingLeft:12, 141 | marginTop:3 142 | }, 143 | playStyle:{ 144 | position:'absolute', 145 | bottom:14, 146 | right:14, 147 | width:46, 148 | height:46, 149 | paddingTop:9, 150 | paddingLeft:18, 151 | backgroundColor:'transparent', 152 | borderColor:'#fff', 153 | borderWidth:1, 154 | borderRadius:23, 155 | color:'#ed7b66' 156 | }, 157 | commentsImageStyle:{ 158 | fontSize:22, 159 | color:"#333" 160 | }, 161 | }); 162 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Component/Picture/Picture.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/13. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View 10 | } from 'react-native'; 11 | 12 | export default class Picture extends Component { 13 | render() { 14 | return ( 15 | 16 | 17 | Picture 18 | 19 | 20 | ); 21 | } 22 | } 23 | 24 | const styles = StyleSheet.create({ 25 | container: { 26 | flex: 1, 27 | justifyContent: 'center', 28 | alignItems: 'center', 29 | backgroundColor: '#F5FCFF', 30 | }, 31 | welcome: { 32 | fontSize: 20, 33 | textAlign: 'center', 34 | margin: 10, 35 | }, 36 | }); -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/RTTabBar.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | TouchableOpacity, 13 | View 14 | } from 'react-native'; 15 | 16 | import Icon from 'react-native-vector-icons/Ionicons'; 17 | 18 | export default class RTTabBar extends Component { 19 | static propTypes = { 20 | 21 | 22 | goToPage: React.PropTypes.func, // 跳转到对应tab的方法 23 | activeTab: React.PropTypes.number, // 当前被选中的tab下标 24 | tabs: React.PropTypes.array, // 所有tabs集合 25 | 26 | tabNames: React.PropTypes.array, // 保存Tab名称 27 | tabIconNames: React.PropTypes.array, // 保存Tab图标 28 | 29 | }; // 注意这里有分号 30 | 31 | 32 | render() { 33 | return ( 34 | 35 | {this.props.tabs.map((tab, i) => this.renderTabOption(tab, i))} 36 | 37 | ); 38 | } 39 | 40 | componentDidMount() { 41 | // Animated.Value监听范围 [0, tab数量-1] 42 | this.props.scrollValue.addListener(this.setAnimationValue); 43 | } 44 | 45 | setAnimationValue({value}) { 46 | // console.log('动画值:'+value); 47 | } 48 | 49 | 50 | renderTabOption(tab, i) { 51 | let color = this.props.activeTab == i ? "#56abe4" : "red"; // 判断i是否是当前选中的tab,设置不同的颜色 52 | return ( 53 | this.props.goToPage(i)} style={styles.tab} key={tab}> 54 | 55 | 59 | 60 | {this.props.tabNames[i]} 61 | 62 | 63 | 64 | ); 65 | } 66 | 67 | 68 | } 69 | 70 | const styles = StyleSheet.create({ 71 | tabs: { 72 | flexDirection: 'row', 73 | height: 50, 74 | }, 75 | 76 | tab: { 77 | flex: 1, 78 | justifyContent: 'center', 79 | alignItems: 'center', 80 | }, 81 | 82 | tabItem: { 83 | flexDirection: 'column', 84 | alignItems: 'center', 85 | }, 86 | 87 | }); 88 | 89 | -------------------------------------------------------------------------------- /Example/App/Page/TwoPage/Two.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/12. 3 | */ 4 | import React, { Component } from 'react'; 5 | import { 6 | AppRegistry, 7 | StyleSheet, 8 | Text, 9 | View, 10 | InteractionManager, 11 | Navigator, 12 | AsyncStorage 13 | } from 'react-native'; 14 | 15 | import RTTabBar from './RTTabBar'; 16 | import ScrollableTabView, {DefaultTabBar, ScrollableTabBar} from 'react-native-scrollable-tab-view'; 17 | import Icon from 'react-native-vector-icons/Ionicons'; 18 | import IconFont from 'react-native-vector-icons/FontAwesome'; 19 | 20 | import Account from './Component/Account/Account'; 21 | import Login from './Component/Account/Login' 22 | import Edit from './Component/Edit/Edit'; 23 | import List from './Component/List/List'; 24 | import Picture from './Component/Picture/Picture'; 25 | 26 | // import RTBar from './RTBar'; 27 | 28 | export default class Baby extends Component{ 29 | constructor(props) { 30 | super(props); 31 | this.state = { 32 | tabNames: ['视频', '录制', '图片', '我的'], 33 | tabIconNames: ['ios-videocam', 'ios-recording', 'ios-reverse-camera', 'ios-contact'], 34 | isLogin:false, // 是否登录 35 | user:null, // 用户信息 36 | 37 | }; 38 | // 获取用户状态 39 | this.asynGetAppStatus = this.asynGetAppStatus.bind(this); 40 | // 登录之后 41 | this.afterLogin = this.afterLogin.bind(this); 42 | } 43 | 44 | afterLogin(data){ 45 | // user 是一个对象,里面放着用户信息 46 | let user = JSON.stringify(data); 47 | AsyncStorage.setItem('user',user) 48 | .then(()=>{ 49 | this.setState({ 50 | isLogin:true, 51 | user:data 52 | }) 53 | }) 54 | .catch((error)=>{ 55 | console.log(error); 56 | alert(error); 57 | }); 58 | } 59 | 60 | asynGetAppStatus(){ 61 | AsyncStorage.getItem('user') 62 | .then((data)=>{ 63 | let user; 64 | let newState = {}; 65 | if(data){ 66 | user = JSON.parse(data); 67 | } 68 | // 判断user是否存在 69 | if (user && user.accessToken){ 70 | newState.isLogin = true; 71 | newState.user = user; 72 | }else { 73 | newState.isLogin = false; 74 | } 75 | this.setState(newState); 76 | }) 77 | .catch((error)=>{ 78 | alert(error) 79 | }); 80 | } 81 | 82 | componentDidMount() { 83 | this.asynGetAppStatus(); 84 | } 85 | 86 | render() { 87 | let tabNames = this.state.tabNames; 88 | let tabIconNames = this.state.tabIconNames; 89 | // 判断是否登录,如果没有登录跳转到登录页面, 如果登录进入首页 90 | if (!this.state.isLogin){ 91 | return 92 | } 93 | return ( 94 | // tabLabel="RTBar" 95 | 96 | { 100 | if (route.sceneConfig) { 101 | return route.sceneConfig; 102 | } 103 | return Navigator.SceneConfigs.FloatFromRight; 104 | } } 105 | renderScene={(route, navigator) => { 106 | let Component = route.component; 107 | return ( 108 | 109 | ) 110 | } } 111 | /> 112 | 113 | 114 | 115 | ); 116 | } 117 | onDidFocus(name){ 118 | 119 | } 120 | } 121 | 122 | class RTBar extends Component{ 123 | constructor(props) { 124 | super(props); 125 | this.state = { 126 | tabNames: ['视频', '录制', '图片', '我的'], 127 | tabIconNames: ['ios-videocam', 'ios-recording', 'ios-reverse-camera', 'ios-contact'], 128 | 129 | }; 130 | } 131 | render() { 132 | let tabNames = this.state.tabNames; 133 | let tabIconNames = this.state.tabIconNames; 134 | return ( 135 | } 137 | renderTabBar={() => } 138 | tabBarPosition='overlayBottom' 139 | onChangeTab={ 140 | (obj) => { 141 | {/*console.log('被选中的tab下标:' + obj.i);*/} 142 | } 143 | } 144 | onScroll={ 145 | (position) => { 146 | {/*console.log('滑动时的位置:' + position);*/} 147 | } 148 | } 149 | locked={false} 150 | initialPage={0} 151 | prerenderingSiblingsNumber={1} 152 | 153 | > 154 | 155 | 156 | 157 | 158 | 159 | 160 | ); 161 | } 162 | } 163 | 164 | 165 | const styles = StyleSheet.create({ 166 | container: { 167 | flex: 1, 168 | justifyContent: 'center', 169 | alignItems: 'center', 170 | backgroundColor: '#F5FCFF', 171 | }, 172 | center: { 173 | flex: 1, 174 | justifyContent: 'center', 175 | alignItems: 'center', 176 | }, 177 | instructions: { 178 | textAlign: 'center', 179 | color: '#333333', 180 | marginBottom: 5, 181 | }, 182 | }); 183 | -------------------------------------------------------------------------------- /Example/App/Root.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Created by SLPower on 2016/10/7. 3 | */ 4 | import React, { Component } from 'react'; 5 | import App from './Base/App'; 6 | 7 | export default class Root extends Component { 8 | render() { 9 | return ( 10 | 11 | ) 12 | } 13 | } -------------------------------------------------------------------------------- /Example/__tests__/index.android.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.android.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /Example/__tests__/index.ios.js: -------------------------------------------------------------------------------- 1 | import 'react-native'; 2 | import React from 'react'; 3 | import Index from '../index.ios.js'; 4 | 5 | // Note: test renderer must be required after react-native. 6 | import renderer from 'react-test-renderer'; 7 | 8 | it('renders correctly', () => { 9 | const tree = renderer.create( 10 | 11 | ); 12 | }); 13 | -------------------------------------------------------------------------------- /Example/android/app/BUCK: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | # To learn about Buck see [Docs](https://buckbuild.com/). 4 | # To run your application with Buck: 5 | # - install Buck 6 | # - `npm start` - to start the packager 7 | # - `cd android` 8 | # - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"` 9 | # - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck 10 | # - `buck install -r android/app` - compile, install and run application 11 | # 12 | 13 | lib_deps = [] 14 | for jarfile in glob(['libs/*.jar']): 15 | name = 'jars__' + re.sub(r'^.*/([^/]+)\.jar$', r'\1', jarfile) 16 | lib_deps.append(':' + name) 17 | prebuilt_jar( 18 | name = name, 19 | binary_jar = jarfile, 20 | ) 21 | 22 | for aarfile in glob(['libs/*.aar']): 23 | name = 'aars__' + re.sub(r'^.*/([^/]+)\.aar$', r'\1', aarfile) 24 | lib_deps.append(':' + name) 25 | android_prebuilt_aar( 26 | name = name, 27 | aar = aarfile, 28 | ) 29 | 30 | android_library( 31 | name = 'all-libs', 32 | exported_deps = lib_deps 33 | ) 34 | 35 | android_library( 36 | name = 'app-code', 37 | srcs = glob([ 38 | 'src/main/java/**/*.java', 39 | ]), 40 | deps = [ 41 | ':all-libs', 42 | ':build_config', 43 | ':res', 44 | ], 45 | ) 46 | 47 | android_build_config( 48 | name = 'build_config', 49 | package = 'com.example', 50 | ) 51 | 52 | android_resource( 53 | name = 'res', 54 | res = 'src/main/res', 55 | package = 'com.example', 56 | ) 57 | 58 | android_binary( 59 | name = 'app', 60 | package_type = 'debug', 61 | manifest = 'src/main/AndroidManifest.xml', 62 | keystore = '//android/keystores:debug', 63 | deps = [ 64 | ':app-code', 65 | ], 66 | ) 67 | -------------------------------------------------------------------------------- /Example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: "com.android.application" 2 | 3 | import com.android.build.OutputFile 4 | 5 | /** 6 | * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets 7 | * and bundleReleaseJsAndAssets). 8 | * These basically call `react-native bundle` with the correct arguments during the Android build 9 | * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the 10 | * bundle directly from the development server. Below you can see all the possible configurations 11 | * and their defaults. If you decide to add a configuration block, make sure to add it before the 12 | * `apply from: "../../node_modules/react-native/react.gradle"` line. 13 | * 14 | * project.ext.react = [ 15 | * // the name of the generated asset file containing your JS bundle 16 | * bundleAssetName: "index.android.bundle", 17 | * 18 | * // the entry file for bundle generation 19 | * entryFile: "index.android.js", 20 | * 21 | * // whether to bundle JS and assets in debug mode 22 | * bundleInDebug: false, 23 | * 24 | * // whether to bundle JS and assets in release mode 25 | * bundleInRelease: true, 26 | * 27 | * // whether to bundle JS and assets in another build variant (if configured). 28 | * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants 29 | * // The configuration property can be in the following formats 30 | * // 'bundleIn${productFlavor}${buildType}' 31 | * // 'bundleIn${buildType}' 32 | * // bundleInFreeDebug: true, 33 | * // bundleInPaidRelease: true, 34 | * // bundleInBeta: true, 35 | * 36 | * // the root of your project, i.e. where "package.json" lives 37 | * root: "../../", 38 | * 39 | * // where to put the JS bundle asset in debug mode 40 | * jsBundleDirDebug: "$buildDir/intermediates/assets/debug", 41 | * 42 | * // where to put the JS bundle asset in release mode 43 | * jsBundleDirRelease: "$buildDir/intermediates/assets/release", 44 | * 45 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 46 | * // require('./image.png')), in debug mode 47 | * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug", 48 | * 49 | * // where to put drawable resources / React Native assets, e.g. the ones you use via 50 | * // require('./image.png')), in release mode 51 | * resourcesDirRelease: "$buildDir/intermediates/res/merged/release", 52 | * 53 | * // by default the gradle tasks are skipped if none of the JS files or assets change; this means 54 | * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to 55 | * // date; if you have any other folders that you want to ignore for performance reasons (gradle 56 | * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/ 57 | * // for example, you might want to remove it from here. 58 | * inputExcludes: ["android/**", "ios/**"], 59 | * 60 | * // override which node gets called and with what additional arguments 61 | * nodeExecutableAndArgs: ["node"] 62 | * 63 | * // supply additional arguments to the packager 64 | * extraPackagerArgs: [] 65 | * ] 66 | */ 67 | 68 | apply from: "../../node_modules/react-native/react.gradle" 69 | 70 | /** 71 | * Set this to true to create two separate APKs instead of one: 72 | * - An APK that only works on ARM devices 73 | * - An APK that only works on x86 devices 74 | * The advantage is the size of the APK is reduced by about 4MB. 75 | * Upload all the APKs to the Play Store and people will download 76 | * the correct one based on the CPU architecture of their device. 77 | */ 78 | def enableSeparateBuildPerCPUArchitecture = false 79 | 80 | /** 81 | * Run Proguard to shrink the Java bytecode in release builds. 82 | */ 83 | def enableProguardInReleaseBuilds = false 84 | 85 | android { 86 | compileSdkVersion 23 87 | buildToolsVersion "23.0.1" 88 | 89 | defaultConfig { 90 | applicationId "com.example" 91 | minSdkVersion 16 92 | targetSdkVersion 22 93 | versionCode 1 94 | versionName "1.0" 95 | ndk { 96 | abiFilters "armeabi-v7a", "x86" 97 | } 98 | } 99 | splits { 100 | abi { 101 | reset() 102 | enable enableSeparateBuildPerCPUArchitecture 103 | universalApk false // If true, also generate a universal APK 104 | include "armeabi-v7a", "x86" 105 | } 106 | } 107 | buildTypes { 108 | release { 109 | minifyEnabled enableProguardInReleaseBuilds 110 | proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro" 111 | } 112 | } 113 | // applicationVariants are e.g. debug, release 114 | applicationVariants.all { variant -> 115 | variant.outputs.each { output -> 116 | // For each separate APK per architecture, set a unique version code as described here: 117 | // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits 118 | def versionCodes = ["armeabi-v7a":1, "x86":2] 119 | def abi = output.getFilter(OutputFile.ABI) 120 | if (abi != null) { // null for the universal-debug, universal-release variants 121 | output.versionCodeOverride = 122 | versionCodes.get(abi) * 1048576 + defaultConfig.versionCode 123 | } 124 | } 125 | } 126 | } 127 | 128 | dependencies { 129 | compile project(':react-native-vector-icons') 130 | compile project(':react-native-image-picker') 131 | compile project(':react-native-video') 132 | compile fileTree(dir: "libs", include: ["*.jar"]) 133 | compile "com.android.support:appcompat-v7:23.0.1" 134 | compile "com.facebook.react:react-native:+" // From node_modules 135 | } 136 | 137 | // Run this once to be able to run the application with BUCK 138 | // puts all compile dependencies into folder libs for BUCK to use 139 | task copyDownloadableDepsToLibs(type: Copy) { 140 | from configurations.compile 141 | into 'libs' 142 | } 143 | -------------------------------------------------------------------------------- /Example/android/app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /usr/local/Cellar/android-sdk/24.3.3/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Disabling obfuscation is useful if you collect stack traces from production crashes 20 | # (unless you are using a system that supports de-obfuscate the stack traces). 21 | -dontobfuscate 22 | 23 | # React Native 24 | 25 | # Keep our interfaces so they can be used by other ProGuard rules. 26 | # See http://sourceforge.net/p/proguard/bugs/466/ 27 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.DoNotStrip 28 | -keep,allowobfuscation @interface com.facebook.proguard.annotations.KeepGettersAndSetters 29 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 30 | 31 | # Do not strip any method/class that is annotated with @DoNotStrip 32 | -keep @com.facebook.proguard.annotations.DoNotStrip class * 33 | -keep @com.facebook.common.internal.DoNotStrip class * 34 | -keepclassmembers class * { 35 | @com.facebook.proguard.annotations.DoNotStrip *; 36 | @com.facebook.common.internal.DoNotStrip *; 37 | } 38 | 39 | -keepclassmembers @com.facebook.proguard.annotations.KeepGettersAndSetters class * { 40 | void set*(***); 41 | *** get*(); 42 | } 43 | 44 | -keep class * extends com.facebook.react.bridge.JavaScriptModule { *; } 45 | -keep class * extends com.facebook.react.bridge.NativeModule { *; } 46 | -keepclassmembers,includedescriptorclasses class * { native ; } 47 | -keepclassmembers class * { @com.facebook.react.uimanager.UIProp ; } 48 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactProp ; } 49 | -keepclassmembers class * { @com.facebook.react.uimanager.annotations.ReactPropGroup ; } 50 | 51 | -dontwarn com.facebook.react.** 52 | 53 | # okhttp 54 | 55 | -keepattributes Signature 56 | -keepattributes *Annotation* 57 | -keep class okhttp3.** { *; } 58 | -keep interface okhttp3.** { *; } 59 | -dontwarn okhttp3.** 60 | 61 | # okio 62 | 63 | -keep class sun.misc.Unsafe { *; } 64 | -dontwarn java.nio.file.* 65 | -dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement 66 | -dontwarn okio.** 67 | -------------------------------------------------------------------------------- /Example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 19 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/Entypo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/Entypo.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/EvilIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/EvilIcons.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/Foundation.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/Foundation.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/Ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/Ionicons.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/MaterialIcons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/MaterialIcons.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/Octicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/Octicons.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/assets/fonts/Zocial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/assets/fonts/Zocial.ttf -------------------------------------------------------------------------------- /Example/android/app/src/main/java/com/example/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import com.facebook.react.ReactActivity; 4 | import com.brentvatne.react.ReactVideoPackage; 5 | 6 | public class MainActivity extends ReactActivity { 7 | 8 | /** 9 | * Returns the name of the main component registered from JavaScript. 10 | * This is used to schedule rendering of the component. 11 | */ 12 | @Override 13 | protected String getMainComponentName() { 14 | return "Example"; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/android/app/src/main/java/com/example/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.example; 2 | 3 | import android.app.Application; 4 | import android.util.Log; 5 | 6 | import com.facebook.react.ReactApplication; 7 | import com.oblador.vectoricons.VectorIconsPackage; 8 | import com.imagepicker.ImagePickerPackage; 9 | import com.facebook.react.ReactInstanceManager; 10 | import com.facebook.react.ReactNativeHost; 11 | import com.facebook.react.ReactPackage; 12 | import com.facebook.react.shell.MainReactPackage; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | 17 | public class MainApplication extends Application implements ReactApplication { 18 | 19 | private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { 20 | @Override 21 | protected boolean getUseDeveloperSupport() { 22 | return BuildConfig.DEBUG; 23 | } 24 | 25 | @Override 26 | protected List getPackages() { 27 | return Arrays.asList( 28 | new MainReactPackage(), 29 | new VectorIconsPackage(), 30 | new ImagePickerPackage() 31 | ); 32 | } 33 | }; 34 | 35 | @Override 36 | public ReactNativeHost getReactNativeHost() { 37 | return mReactNativeHost; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /Example/android/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Example 4 | 5 | -------------------------------------------------------------------------------- /Example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/android/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:1.3.1' 9 | 10 | // NOTE: Do not place your application dependencies here; they belong 11 | // in the individual module build.gradle files 12 | } 13 | } 14 | 15 | allprojects { 16 | repositories { 17 | mavenLocal() 18 | jcenter() 19 | maven { 20 | // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm 21 | url "$rootDir/../node_modules/react-native/android" 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true 19 | 20 | android.useDeprecatedNdk=true 21 | -------------------------------------------------------------------------------- /Example/android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /Example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip 6 | -------------------------------------------------------------------------------- /Example/android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /Example/android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /Example/android/keystores/BUCK: -------------------------------------------------------------------------------- 1 | keystore( 2 | name = 'debug', 3 | store = 'debug.keystore', 4 | properties = 'debug.keystore.properties', 5 | visibility = [ 6 | 'PUBLIC', 7 | ], 8 | ) 9 | -------------------------------------------------------------------------------- /Example/android/keystores/debug.keystore.properties: -------------------------------------------------------------------------------- 1 | key.store=debug.keystore 2 | key.alias=androiddebugkey 3 | key.store.password=android 4 | key.alias.password=android 5 | -------------------------------------------------------------------------------- /Example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'Example' 2 | 3 | include ':app' 4 | include ':react-native-vector-icons' 5 | project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android') 6 | include ':react-native-image-picker' 7 | project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android') 8 | include ':react-native-video' 9 | project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android') 10 | -------------------------------------------------------------------------------- /Example/index.android.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | export default class Example extends Component { 16 | render() { 17 | return ( 18 | 19 | 20 | Welcome to React Native! 21 | 22 | 23 | To get started, edit index.android.js 24 | 25 | 26 | Double tap R on your keyboard to reload,{'\n'} 27 | Shake or press menu button for dev menu 28 | 29 | 30 | ); 31 | } 32 | } 33 | 34 | 35 | const styles = StyleSheet.create({ 36 | container: { 37 | flex: 1, 38 | justifyContent: 'center', 39 | alignItems: 'center', 40 | backgroundColor: '#F5FCFF', 41 | }, 42 | welcome: { 43 | fontSize: 20, 44 | textAlign: 'center', 45 | margin: 10, 46 | }, 47 | instructions: { 48 | textAlign: 'center', 49 | color: '#333333', 50 | marginBottom: 5, 51 | }, 52 | }); 53 | 54 | AppRegistry.registerComponent('Example', () => Example); 55 | -------------------------------------------------------------------------------- /Example/index.ios.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Sample React Native App 3 | * https://github.com/facebook/react-native 4 | * @flow 5 | */ 6 | 7 | import React, { Component } from 'react'; 8 | import { 9 | AppRegistry, 10 | StyleSheet, 11 | Text, 12 | View 13 | } from 'react-native'; 14 | 15 | import Root from './App/Root'; 16 | import Two from './App/Page/ThreePage/Three' 17 | 18 | 19 | AppRegistry.registerComponent('Example', () => Root); 20 | -------------------------------------------------------------------------------- /Example/ios/Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 78 | 80 | 86 | 87 | 88 | 89 | 93 | 94 | 95 | 96 | 97 | 98 | 104 | 106 | 112 | 113 | 114 | 115 | 117 | 118 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /Example/ios/Example/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Example/ios/Example/Controller/PushController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PushController.h 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/12. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface PushController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/ios/Example/Controller/PushController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PushController.m 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/12. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import "PushController.h" 10 | #import "AppDelegate.h" 11 | #import "RCTRootView.h" 12 | #import "RCTBundleURLProvider.h" 13 | 14 | @interface PushController () 15 | 16 | @end 17 | 18 | @implementation PushController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | self.view.backgroundColor = [UIColor whiteColor]; 24 | 25 | self.navigationItem.title = @"我是ReactNative页面呦~"; 26 | 27 | NSURL *jsCodeLocation; 28 | 29 | // 另外一种可以获得RN的类方法 30 | // jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:[NSString stringWithFormat:@"./App/Page/ThreePage/Three"] fallbackResource:nil]; 31 | 32 | NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"; 33 | 34 | jsCodeLocation = [NSURL URLWithString:strUrl]; 35 | 36 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 37 | moduleName:@"Three" 38 | initialProperties:@{ 39 | 40 | @"launchOptions":@{ 41 | @"componentName":@"PageOne" 42 | } 43 | } 44 | launchOptions:nil]; 45 | self.view = rootView; 46 | 47 | } 48 | 49 | //- (void)viewWillAppear:(BOOL)animated{ 50 | // AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 51 | // [app.nav setNavigationBarHidden:NO animated:animated]; 52 | // [super viewWillAppear:animated]; 53 | //} 54 | // 55 | //- (void)viewWillDisappear:(BOOL)animated{ 56 | // AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 57 | // [app.nav setNavigationBarHidden:YES animated:animated]; 58 | // [super viewWillDisappear:animated]; 59 | //} 60 | 61 | @end 62 | -------------------------------------------------------------------------------- /Example/ios/Example/Controller/TestController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TestController.h 3 | // Example 4 | // 5 | // Copyright © 2016年 Facebook. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | 11 | @interface TestController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/ios/Example/Controller/TestController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TestController.m 3 | // Example 4 | // 5 | // Copyright © 2016年 Facebook. All rights reserved. 6 | // 7 | 8 | #import "TestController.h" 9 | #import "PushController.h" 10 | 11 | #import "AppDelegate.h" 12 | 13 | #define SCREEN_WIDTH [UIScreen mainScreen].bounds.size.width 14 | #define SCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height 15 | 16 | 17 | @interface TestController () 18 | 19 | @end 20 | 21 | @implementation TestController 22 | 23 | - (void)viewWillAppear:(BOOL)animated{ 24 | AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 25 | [app.nav setNavigationBarHidden:NO animated:animated]; 26 | [super viewWillAppear:animated]; 27 | } 28 | 29 | - (void)viewWillDisappear:(BOOL)animated{ 30 | AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 31 | [app.nav setNavigationBarHidden:YES animated:animated]; 32 | [super viewWillDisappear:animated]; 33 | } 34 | 35 | - (void)viewDidLoad { 36 | [super viewDidLoad]; 37 | 38 | self.navigationItem.title = @"我是原生页面哟~"; 39 | 40 | self.view.backgroundColor = [UIColor whiteColor]; 41 | 42 | 43 | UIButton *button = [UIButton buttonWithType:(UIButtonTypeCustom)]; 44 | button.frame = CGRectMake(SCREEN_WIDTH / 2 - 150, 80, 300, 80); 45 | button.backgroundColor = [UIColor redColor]; 46 | [button setTitle:@"点击我,跳转到React-Native页面" forState:(UIControlStateNormal)]; 47 | [button addTarget:self action:@selector(click) forControlEvents:(UIControlEventTouchUpInside)]; 48 | [self.view addSubview:button]; 49 | 50 | } 51 | 52 | - (void)click{ 53 | 54 | PushController *push = [[PushController alloc]init]; 55 | [self.navigationController pushViewController:push animated:YES]; 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | } 43 | ], 44 | "info" : { 45 | "version" : 1, 46 | "author" : "xcode" 47 | } 48 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/周期.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "周期.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/周期.imageset/周期.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/ios/Example/Images.xcassets/周期.imageset/周期.png -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/宝宝.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "宝宝.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/宝宝.imageset/宝宝.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/ios/Example/Images.xcassets/宝宝.imageset/宝宝.png -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/新闻.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "新闻.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/新闻.imageset/新闻.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/ios/Example/Images.xcassets/新闻.imageset/新闻.png -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/跳转.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "跳转.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/跳转.imageset/跳转.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/ios/Example/Images.xcassets/跳转.imageset/跳转.png -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/闹钟.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "闹钟.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "idiom" : "universal", 14 | "scale" : "3x" 15 | } 16 | ], 17 | "info" : { 18 | "version" : 1, 19 | "author" : "xcode" 20 | } 21 | } -------------------------------------------------------------------------------- /Example/ios/Example/Images.xcassets/闹钟.imageset/闹钟.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeRabbitYu/react-native-learn/66b2c149989d1feeb0062cd56de4322fab1a9559/Example/ios/Example/Images.xcassets/闹钟.imageset/闹钟.png -------------------------------------------------------------------------------- /Example/ios/Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSAppTransportSecurity 6 | 7 | NSAllowsArbitraryLoads 8 | 9 | 10 | UIAppFonts 11 | 12 | Zocial.ttf 13 | Octicons.ttf 14 | MaterialIcons.ttf 15 | Ionicons.ttf 16 | Foundation.ttf 17 | FontAwesome.ttf 18 | EvilIcons.ttf 19 | Entypo.ttf 20 | Entypo.ttf 21 | EvilIcons.ttf 22 | FontAwesome.ttf 23 | Foundation.ttf 24 | Ionicons.ttf 25 | MaterialIcons.ttf 26 | Octicons.ttf 27 | Zocial.ttf 28 | 29 | CFBundleDevelopmentRegion 30 | en 31 | CFBundleExecutable 32 | $(EXECUTABLE_NAME) 33 | CFBundleIdentifier 34 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 35 | CFBundleInfoDictionaryVersion 36 | 6.0 37 | CFBundleName 38 | $(PRODUCT_NAME) 39 | CFBundlePackageType 40 | APPL 41 | CFBundleShortVersionString 42 | 1.0 43 | CFBundleSignature 44 | ???? 45 | CFBundleVersion 46 | 1 47 | LSRequiresIPhoneOS 48 | 49 | UILaunchStoryboardName 50 | LaunchScreen 51 | UIRequiredDeviceCapabilities 52 | 53 | armv7 54 | 55 | UISupportedInterfaceOrientations 56 | 57 | UIInterfaceOrientationPortrait 58 | UIInterfaceOrientationLandscapeLeft 59 | UIInterfaceOrientationLandscapeRight 60 | 61 | UIViewControllerBasedStatusBarAppearance 62 | 63 | NSLocationWhenInUseUsageDescription 64 | 65 | 66 | -------------------------------------------------------------------------------- /Example/ios/Example/Main/AppDelegate.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | @interface AppDelegate : UIResponder 13 | 14 | @property (nonatomic, strong) UIWindow *window; 15 | 16 | // 创建一个原生的导航条 17 | @property (nonatomic, strong) UINavigationController *nav; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Example/ios/Example/Main/AppDelegate.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import "AppDelegate.h" 11 | 12 | #import "TestController.h" 13 | 14 | #import "RCTBundleURLProvider.h" 15 | #import "RCTRootView.h" 16 | 17 | @implementation AppDelegate 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 20 | { 21 | NSURL *jsCodeLocation; 22 | 23 | jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil]; 24 | 25 | RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 26 | moduleName:@"Example" 27 | initialProperties:nil 28 | launchOptions:launchOptions]; 29 | rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; 30 | 31 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; 32 | UIViewController *rootViewController = [UIViewController new]; 33 | rootViewController.view = rootView; 34 | rootViewController.navigationItem.title = @"Hello World!"; 35 | 36 | // 初始化Nav 37 | _nav = [[UINavigationController alloc]initWithRootViewController:rootViewController]; 38 | _nav.navigationBarHidden = YES; 39 | self.window.rootViewController = _nav; 40 | [self.window makeKeyAndVisible]; 41 | 42 | 43 | 44 | 45 | return YES; 46 | } 47 | 48 | 49 | 50 | @end 51 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN组件/ReactView.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReactView.h 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/9. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ReactView : UIView 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN组件/ReactView.m: -------------------------------------------------------------------------------- 1 | // 2 | // ReactView.m 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/9. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import "ReactView.h" 10 | 11 | #import 12 | 13 | @implementation ReactView 14 | 15 | // 这是一个封装好的react-native页面 16 | 17 | - (instancetype)initWithFrame:(CGRect)frame 18 | { 19 | if (self = [super initWithFrame:frame]) { 20 | NSString * strUrl = @"http://localhost:8081/index.ios.bundle?platform=ios&dev=true"; 21 | NSURL * jsCodeLocation = [NSURL URLWithString:strUrl]; 22 | // 这里的moduleName一定要和下面的index.ios.js里面的注册一样 23 | RCTRootView * rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation 24 | moduleName:@"Three" 25 | initialProperties:nil 26 | launchOptions:nil]; 27 | 28 | [self addSubview:rootView]; 29 | 30 | rootView.frame = self.bounds; 31 | } 32 | return self; 33 | } 34 | 35 | @end 36 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN需要组件/PushNative.h: -------------------------------------------------------------------------------- 1 | // 2 | // PushNative.h 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/10/31. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "RCTBridgeModule.h" 11 | 12 | @interface PushNative : NSObject 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN需要组件/PushNative.m: -------------------------------------------------------------------------------- 1 | // 2 | // PushNative.m 3 | // Example 4 | // 5 | // Copyright © 2016年 Facebook. All rights reserved. 6 | // 7 | 8 | #import "PushNative.h" 9 | #import "RCTBridge.h" 10 | 11 | #import "TestController.h" 12 | #import "AppDelegate.h" 13 | 14 | #import "RCTViewManager.h" 15 | 16 | @implementation PushNative 17 | 18 | RCT_EXPORT_MODULE() 19 | //RN跳转原生界面 20 | RCT_EXPORT_METHOD(RNOpenOneVC:(NSString *)msg){ 21 | 22 | NSLog(@"RN传入原生界面的数据为:%@",msg); 23 | //主要这里必须使用主线程发送,不然有可能失效 24 | dispatch_async(dispatch_get_main_queue(), ^{ 25 | // [[NSNotificationCenter defaultCenter]postNotificationName:@"RNOpenOneVC" object:nil]; 26 | TestController *one = [[TestController alloc]init]; 27 | 28 | AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate]; 29 | 30 | [app.nav pushViewController:one animated:YES]; 31 | }); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN需要组件/RCTPushViewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // RCTPushViewManager.h 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/14. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import "RCTViewManager.h" 10 | #import "PushButton.h" 11 | @interface RCTPushViewManager : RCTViewManager 12 | 13 | /** <#type#> */ 14 | @property (nonatomic, strong) PushButton *button; 15 | 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/RN需要组件/RCTPushViewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // RCTPushViewManager.m 3 | // Example 4 | // 5 | // Created by 郭洪安 on 2016/11/14. 6 | // Copyright © 2016年 Facebook. All rights reserved. 7 | // 8 | 9 | #import "RCTPushViewManager.h" 10 | 11 | @implementation RCTPushViewManager 12 | 13 | RCT_EXPORT_MODULE() 14 | @synthesize bridge = _bridge; 15 | 16 | - (UIView *)view 17 | { 18 | _button = [[PushButton alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 19 | _button.ClickDelagate = self; 20 | return _button; 21 | 22 | } 23 | 24 | RCT_EXPORT_VIEW_PROPERTY(btnTitle, NSString) 25 | 26 | RCT_EXPORT_VIEW_PROPERTY(onButtonClicked, RCTBubblingEventBlock) 27 | 28 | 29 | - (void)ButtonClicked { 30 | NSInteger x = arc4random() % 100; 31 | NSLog(@"原生事件%ld",x); 32 | _button.onButtonClicked(@{@"randomValue": [NSNumber numberWithInteger:x]}); 33 | } 34 | 35 | - (dispatch_queue_t)methodQueue 36 | { 37 | return dispatch_get_main_queue(); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/原生组件/PushButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // PushButton.h 3 | // Example 4 | // 5 | // Copyright © 2016年 Facebook. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | #import "RCTComponent.h" 11 | 12 | // 这是一个封装好的react-native页面 13 | 14 | @protocol PushButtonClickedDelegate 15 | 16 | - (void)ButtonClicked; 17 | 18 | @end 19 | 20 | @interface PushButton : UIButton 21 | 22 | @property (nonatomic, copy) NSString * btnTitle;//分享的文本 23 | /** button点击事件 */ 24 | @property (nonatomic, copy) RCTBubblingEventBlock onButtonClicked; 25 | 26 | @property (nonatomic, strong) id ClickDelagate; 27 | 28 | @end 29 | 30 | -------------------------------------------------------------------------------- /Example/ios/Example/Project/原生组件/PushButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // PushButton.m 3 | // Example 4 | // 5 | // Copyright © 2016年 Facebook. All rights reserved. 6 | // 7 | 8 | #import "PushButton.h" 9 | 10 | @implementation PushButton 11 | 12 | - (instancetype) initWithFrame:(CGRect)frame{ 13 | if ((self = [super initWithFrame:frame])) { 14 | [self setTitle:@"Cain" forState:UIControlStateNormal]; 15 | [self addTarget:self action:@selector(click) 16 | forControlEvents:UIControlEventTouchUpInside]; 17 | } 18 | return self; 19 | } 20 | 21 | // 按钮分享事件 22 | - (void)click { 23 | NSLog(@"我是原生按钮点击事件呦"); 24 | [self.ClickDelagate ButtonClicked]; 25 | } 26 | 27 | - (void)setBtnTitle:(NSString *)btnTitle{ 28 | [self setTitle:btnTitle forState:(UIControlStateNormal)]; 29 | } 30 | 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Example/ios/Example/main.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Example/ios/ExampleTests/ExampleTests.m: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright (c) 2015-present, Facebook, Inc. 3 | * All rights reserved. 4 | * 5 | * This source code is licensed under the BSD-style license found in the 6 | * LICENSE file in the root directory of this source tree. An additional grant 7 | * of patent rights can be found in the PATENTS file in the same directory. 8 | */ 9 | 10 | #import 11 | #import 12 | 13 | #import "RCTLog.h" 14 | #import "RCTRootView.h" 15 | 16 | #define TIMEOUT_SECONDS 600 17 | #define TEXT_TO_LOOK_FOR @"Welcome to React Native!" 18 | 19 | @interface ExampleTests : XCTestCase 20 | 21 | @end 22 | 23 | @implementation ExampleTests 24 | 25 | - (BOOL)findSubviewInView:(UIView *)view matching:(BOOL(^)(UIView *view))test 26 | { 27 | if (test(view)) { 28 | return YES; 29 | } 30 | for (UIView *subview in [view subviews]) { 31 | if ([self findSubviewInView:subview matching:test]) { 32 | return YES; 33 | } 34 | } 35 | return NO; 36 | } 37 | 38 | - (void)testRendersWelcomeScreen 39 | { 40 | UIViewController *vc = [[[[UIApplication sharedApplication] delegate] window] rootViewController]; 41 | NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; 42 | BOOL foundElement = NO; 43 | 44 | __block NSString *redboxError = nil; 45 | RCTSetLogFunction(^(RCTLogLevel level, RCTLogSource source, NSString *fileName, NSNumber *lineNumber, NSString *message) { 46 | if (level >= RCTLogLevelError) { 47 | redboxError = message; 48 | } 49 | }); 50 | 51 | while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { 52 | [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 53 | [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; 54 | 55 | foundElement = [self findSubviewInView:vc.view matching:^BOOL(UIView *view) { 56 | if ([view.accessibilityLabel isEqualToString:TEXT_TO_LOOK_FOR]) { 57 | return YES; 58 | } 59 | return NO; 60 | }]; 61 | } 62 | 63 | RCTSetLogFunction(RCTDefaultLogFunction); 64 | 65 | XCTAssertNil(redboxError, @"RedBox error: %@", redboxError); 66 | XCTAssertTrue(foundElement, @"Couldn't find element with text '%@' in %d seconds", TEXT_TO_LOOK_FOR, TIMEOUT_SECONDS); 67 | } 68 | 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /Example/ios/ExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | org.reactjs.native.example.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Example", 3 | "version": "0.0.1", 4 | "private": true, 5 | "scripts": { 6 | "start": "node node_modules/react-native/local-cli/cli.js start", 7 | "test": "jest" 8 | }, 9 | "dependencies": { 10 | "lodash": "^4.16.4", 11 | "mockjs": "^1.0.1-beta3", 12 | "query-string": "^4.2.3", 13 | "react": "15.3.2", 14 | "react-native": "0.35.0", 15 | "react-native-button": "^1.7.1", 16 | "react-native-image-picker": "^0.22.12", 17 | "react-native-navbar": "^1.5.4", 18 | "react-native-scrollable-tab-view": "^0.6.0", 19 | "react-native-scrolling-menu": "^0.1.1", 20 | "react-native-swiper": "^1.5.2", 21 | "react-native-tab-navigator": "^0.3.3", 22 | "react-native-vector-icons": "^2.1.0", 23 | "react-native-video": "^0.9.0", 24 | "react-redux": "^4.4.6", 25 | "redux": "^3.6.0", 26 | "redux-thunk": "^2.1.0", 27 | "wilddog": "^2.3.8" 28 | }, 29 | "jest": { 30 | "preset": "jest-react-native" 31 | }, 32 | "devDependencies": { 33 | "babel-jest": "16.0.0", 34 | "babel-preset-react-native": "1.9.0", 35 | "jest": "16.0.1", 36 | "jest-react-native": "16.0.0", 37 | "react-test-renderer": "15.3.2", 38 | "redux-devtools": "^3.3.1", 39 | "whatwg-fetch": "1.0.0" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Learn React-Native 2 | ## Example 3 | 这个工程是我学习react-native的总结,我会把学到的东西,遇到的问题,总结的经验放在里面,希望以后再遇到问题的时候可以找到解决的办法,也希望可能帮到其他人。 4 | ## OnePage: 5 | 这是一个关于计时器使用的例子,是我通过学习[30-days-of-react-native](https://github.com/fangwei716/30-days-of-react-native)第一天的内容得到的。 6 | ## TwoPage: 7 | 这是一个宝宝秀项目,是照着网上的一个付费视频写的,已经完成了第一个模块的功能开发,有视频播放与暂停,评论功能,接口的调用。这个会一直更新的这个项目结束。 8 | ## ThreePage: 9 | 这是react-native页面跳转到原生页面的案例,过两天会把整个流程完善。 10 | 这个是我之前写的一篇关于[在iOS中创建React-Native页面,并跳转到原生页面](http://www.jianshu.com/p/ffe9e8b8dbe6)的文章, 11 | 今天在简书上更新了一篇文章[在react-native的项目中跳转到原生iOS页面](http://www.jianshu.com/p/2baeac04275e) 12 | ### 经验: 13 | * 计时器的一些使用方式 14 | 15 | `setInterval()` 会不停地调用函数。 16 | 17 | ``` 18 | // 最后的参数指每隔1s调用一次函数 19 | this.setIntervar = setInterval(()=>{},1000) 20 | ``` 21 | 22 | `setTimeout()` 只调用函数一次。 23 | 24 | ``` 25 | this.setTimeout = setTimeout(()=>{},1000) 26 | ``` 27 | 28 | `clearInterval()` 可以关闭setInterval()。 29 | 30 | ``` 31 | this.setIntervar && clearInterval(this.setIntervar); 32 | ``` 33 | 34 | * `InteractionManager`可以将一些耗时较长的工作安排到所有互动或动画完成之后再进行 35 | 36 | ``` 37 | InteractionManager.runAfterInteractions(() => { 38 | // ...耗时较长的同步的任务... 39 | // 比如页面跳转 40 | }); 41 | ``` 42 | 43 | * 这个方法可以得到Navigator的层级关系; 44 | 45 | ``` 46 | var currentRoute = this.props.navigator.getCurrentRoutes(); 47 | ``` 48 | ``` 49 | for(var i = 0 ; i r1 !== r2}); 66 | this.state = { 67 | //默认的参数,可以通过this.setState({})修改里面的参数 68 | dataSource : dataSource, 69 | }; 70 | 71 | // 这里面可以用来绑定this.XXX()方法,也可以用来初始化ListViewDataSource方法 72 | this.XXX = this.XXX.bind(this); 73 | } 74 | ``` 75 | * 不可变的属性,也可以当做跨页面参数来使用,可以通过this.props.XXX获取里面的参数; 76 | 77 | ``` 78 | static defaultProps = { 79 | // 里面写不可变的属性 80 | }; 81 | ``` 82 | 这个方法是用来确定this.props.XXX类型的,如果XXX这个参数不写,就会报错 83 | 84 | ``` 85 | static propTypes = { 86 | // 必须要写的数组 87 | XXX: React.PropTypes.array.isXXX, 88 | }; 89 | ``` 90 | * 生命周期(以后完善) 91 | 92 | ``` 93 | // 程序加载完成的时候调用 94 | componentDidMount(){ 95 | // 一些复杂的操作 96 | // 每隔多少时间 97 | duration:1000 98 | } 99 | ``` 100 | * 三位运算符`{ ? : }` 101 | 在react-native里面用到最多的东西应该就是三位运算符了,它免去了麻烦的判断,只需要根据组件的状态来判断显示什么样页面与数据 102 | * 网络请求 103 | 在react-native中使用最多的就是`fetch`请求了,在`fetch`请求中可以传`url`,`body`参数,也可以请求`GET`,`POST`,`PUT`等方式 104 | 105 | ``` 106 | fetch(url ,{ 107 | method: 'GET', // 这里可以改成POST 108 | // 如果是POST请求,可以将需要请求的参数写在里面 109 | headers: { 110 | 'Accept-Encoding': '', 111 | 'Content-Type': '', 112 | 'User-Agent': '', 113 | } 114 | }) 115 | // 这是一个解析JSON的方法,也可以将response.json()改成response.text()这个需要和后台商量好 116 | .then((response) => response.json()) 117 | .then((responseData)=> { 118 | // responseData就是解析过来的JSON对象 119 | console.log(responseData); 120 | }) 121 | .catch((error)=> { 122 | if (error) { 123 | //特殊处理 124 | console.log(error); 125 | } 126 | }); 127 | ``` 128 | * 在RN里面同一个页面是可以写两个类的,但只能导出一个`export`,一般情况下第二个类都是对第一个的补充,所以最好在第二个类中公开一些方法 129 | 130 | ``` 131 | class ImageItem extends Component { 132 | static defaultProps = { 133 | // 比如说第一个类需要封装一个图片组件,那个给下面的类传一个imageName就可以了 134 | imageName: '', 135 | }; 136 | render(){ 137 | return( 138 | 139 | ) 140 | } 141 | } 142 | ``` 143 | 在第一个组件中通过调用ImageItem就可以了,将需要的参数传过去。 144 | 145 | ``` 146 | 149 | ``` 150 | 151 | 152 | 153 | ### 推荐的第三方开源组件(我只写我用到过的,感觉很不错的库,在后面我会为这些库写一些文章把我遇到的问题写出来) 154 | 1. 导航条组件:[react-native-navbar](https://github.com/react-native-community/react-native-navbar) 155 | 推荐原因:用过系统Navigator组件后,一般都需要自己自定制导航条的按钮和标题,用了这个组件会剩下很多的步骤。这个组件在我的项目中一直用到; 156 | 2. 底部TabBar组件:[react-native-tab-navigator](https://github.com/exponentjs/react-native-tab-navigator) 157 | 推荐原因:多数的APP都会存在底部的选项卡,这个组件就是用来实现这个的。这个组件在我的项目中TwoPage中有用到; 158 | 3. 底部TabBar组件:[react-native-scrollable-tab-view](https://github.com/skv-headless/react-native-scrollable-tab-view) 159 | 推荐原因:用过安卓版微信的用户知道,底部的TabBar是可以左右滚动的,这个组件就可以实现这个功能。这个组件会在之后用到; 160 | 4. 图标:[react-native-vector-icons](https://github.com/oblador/react-native-vector-icons) 161 | 推荐原因:这个组件可以为你省去找UI要图片的步骤,而且这个组件可以用在很多地方,据说使用这个组件会让图标的加载更流畅。这个组件在项目中很多地方有用到; 162 | 5. 轮播图:[react-native-swiper](react-native-swiper) 163 | 推荐原因:这个组件可以用来做为广告轮播图,页面切换等等,反正是很抢到的一个库。这个组件在项目中很多地方有用到; 164 | 6. 视频播放:[react-native-video](http://serve.3ezy.com/github.com/brentvatne/react-native-video/) 165 | 推荐原因:一个类似于HTML5中`