重要知識點補充:
1.require(./) 當前目錄 require(../) 上級目錄
一、TabBarIOS和TabBarIOS.Item組件學習
效果圖:
gif.gif
代碼:
var TabBarIOSDemo = React.createClass({
//初始化函數
getInitialState(){
return{
selectedTabItem:'first'
}},
//UI的布局函數
render(){
return(
<View style={styles.containerStyle}>
<View style={styles.topTitleStyle}>
<Text style={{fontSize: 20,backgroundColor:'red'}}>tabBar切換</Text>
</View>
<TabBarIOS>
{/*第一部分*/}
<TabBarIOS.Item
systemIcon="history"
badge="6"
selected={this.state.selectedTabItem === "first"}
//selectedTarBarItem寫錯了,改為selectedTarItem selectedTarItem寫錯了selectedTabItem
onPress={()=>{this.setState({selectedTabItem:'first'})}}
>
<View style={styles.commonStyle}>
<Text>11</Text>
</View>
</TabBarIOS.Item>
{/*第二部分*/}
<TabBarIOS.Item
systemIcon="search"
badge="8"
selected={this.state.selectedTabItem === "second"}
onPress={()=>{this.setState({selectedTabItem:'second'})}}
>
<View style={styles.commonStyle}>
<Text>22</Text>
</View>
</TabBarIOS.Item>
{/*第三部分*/}
<TabBarIOS.Item
systemIcon="contacts"
selected={this.state.selectedTabItem === "third"}
onPress={()=>{this.setState({selectedTabItem:'third'})}}
>
<View style={styles.commonStyle}>
<Text>33</Text>
</View>
</TabBarIOS.Item>
{/*第四部分*/}
<TabBarIOS.Item
systemIcon="more"
selected={this.state.selectedTabItem === "fourth"}
onPress={()=>{this.setState({selectedTabItem:'fourth'})}}
>
<View style={styles.commonStyle}>
<Text>44</Text>
</View>
</TabBarIOS.Item>
</TabBarIOS>
</View>
);
}
//樣式的設置
const styles = StyleSheet.create({
containerStyle:{
flex:1,
},
topTitleStyle:{
backgroundColor:'yellow',
height:64,
alignItems:'center',
justifyContent:'center',
},
commonStyle:{
alignItems:'center',
justifyContent:'center',
flex:1
}
});
遇到的問題:
問題:代碼寫好之后,tabbar不能進行切換;
自己犯了二個錯誤??:
1)在初始化方法getInitialState中:selectedTabBarItem改為selectedTabItem
2)selectedTarItem寫錯了,改為selectedTabItem
二、網絡請求
報錯信息:NetWork fail
解決方法:因為ios開發里面info.plist需要配置Allow Arbitrary Loads = YES,網絡請求即可
效果圖:
rn.gif
代碼:
index.ios.js:總模塊
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, TabBarIOS} from 'react-native';
//引入外部的js文件
var Main = require('./Component/CJWMain');
var TabBarIOSDemo = React.createClass({
//UI的布局函數
render(){
return(
<Main/>
);
}
});
const styles = StyleSheet.create({});
AppRegistry.registerComponent('lianxi', () => TabBarIOSDemo);
CJWMain.js:頁面切換模塊
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, TabBarIOS, NavigatorIOS} from 'react-native';
var Home = require('../Component/CJWHome');
var Find = require('../Component/CJWFind');
var Message = require('../Component/CJWMassege');
var Mine = require('../Component/CJWMine');
var mainModel = React.createClass({
//初始化函數
getInitialState(){
return {
selectedTabItem:'home'
}
},
//UI的布局函數
render(){
return(
<View style={styles.containerStyle}>
<TabBarIOS>
{/*首頁*/}
<TabBarIOS.Item
icon={require('image!tabbar_home')}
title="首頁"
selected={this.state.selectedTabItem == 'home'}
onPress={()=> {this.setState({ selectedTabItem:'home'})}}
>
<NavigatorIOS
tintColor='orange'
style={{flex:1}}
initialRoute={
{
component:Home,
title:'首頁',
leftButtonIcon:require('image!navigationbar_friendattention_highlighted'),
rightButtonIcon:require('image!navigationbar_pop_highlighted')
}
}
/>
</TabBarIOS.Item>
{/*發現*/}
<TabBarIOS.Item
icon={require('image!tabbar_discover')}
title="發現"
selected={this.state.selectedTabItem == 'find'}
onPress={()=> {this.setState({ selectedTabItem:'find'})}}
>
<NavigatorIOS
tintColor='orange'
style={{flex:1}}
initialRoute={
{
component:Find,
title:'發現',
leftButtonIcon:require('image!navigationbar_friendattention_highlighted'),
rightButtonIcon:require('image!navigationbar_pop_highlighted')
}
}
/>
</TabBarIOS.Item>
{/*消息*/}
<TabBarIOS.Item
icon={require('image!tabbar_message_center')}
title="消息"
selected={this.state.selectedTabItem == 'message'}
onPress={()=> {this.setState({ selectedTabItem:'message'})}}
>
<NavigatorIOS
tintColor='orange'
style={{flex:1}}
initialRoute={
{
component:Message,
title:'消息',
leftButtonIcon:require('image!navigationbar_friendattention_highlighted'),
rightButtonIcon:require('image!navigationbar_pop_highlighted')
}
}
/>
</TabBarIOS.Item>
{/*我的*/}
<TabBarIOS.Item
icon={require('image!tabbar_profile')}
title="我的"
selected={this.state.selectedTabItem == 'mine'}
onPress={()=> {this.setState({ selectedTabItem:'mine'})}}
>
<NavigatorIOS
tintColor='orange'
style={{flex:1}}
initialRoute={
{
component:Mine,
title:'我的',
leftButtonIcon:require('image!navigationbar_friendattention_highlighted'),
rightButtonIcon:require('image!navigationbar_pop_highlighted')
}
}
/>
</TabBarIOS.Item>
</TabBarIOS>
</View>
)
}
});
const styles = StyleSheet.create({
containerStyle:{
flex:1,
}
});
//輸出獨立的類
module.exports = mainModel;
CJWHome.js:網絡請求模塊
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, TabBarIOS, ListView, TouchableOpacity, Image} from 'react-native';
//引入外部的js文件,組件類
var ScrollImage = require('../Component/CJWScrollImage');
var NewsDetail = require('../Component/CJWNewsDetail');
var homeModel = React.createClass({
//初始化函數,不可以改變的值
getDefaultProps(){
return{
url:'http://c.3g.163.com/nc/article/list/T1467284926140/0-20.html',
param:'T1467284926140'
}
},
//初始化函數,可以改變默認值
getInitialState(){
return{
//listview的頭部數據---輪播圖
headerDataArr:[],
//cell的數據源
dataSource:new ListView.DataSource({
rowHasChanged:(r1,r2) => r1 !== r2
})
}
},
//UI的布局函數
render(){
return(
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow}
renderHeader={this.renderHeader}
/>
);
},
//cell的數據處理
renderRow(rowData){
return(
<TouchableOpacity
activeOpacity={0.5}
onPress={()=>this.onPressCell(rowData)}>
<View style={styles.cellStyle}>
{/*左邊的視圖*/}
<Image source={{uri:rowData.imgsrc}} style={styles.imageStyle}/>
{/*右邊的文字*/}
<View style={styles.rightViewStyle}>
<Text style={styles.rightTextStyle}>{rowData.title}</Text>
<Text style={styles.bottomTextStyle}>{rowData.replyCount + '跟帖'}</Text>
</View>
</View>
</TouchableOpacity>
)
},
//頭部視圖
renderHeader(){
if(this.state.headerDataArr.length == 0)return;
return(
<View style={styles.headerViewStyle}>
{/*<Text>頭部視圖</Text>*/}
<ScrollImage
//頁面之間傳值方式一:開始傳值的源頭
imageDataArr={this.state.headerDataArr}
/>
</View>
)
},
//cell的點擊事件
onPressCell(data){
this.props.navigator.push({
component:NewsDetail,
// title:data.title,
title:'新聞詳情',
//頁面之間傳值方式二,??將數據傳遞到詳情頁面
passProps:{data}
})
},
//網絡請求處理
componentDidMount(){
this.loadDataNet();
},
//網絡請求處理
loadDataNet(){
fetch(this.props.url)
.then((response) =>response.json())
.then((responseData) => {
// console.log(responseData);
var headArr = [],listArr = [];
// console.log(responseData[this.props.param]);
var jsonData = responseData[this.props.param];
for (var i = 0; i < jsonData.length;i ++){
if(jsonData[i].hasAD == 1){
headArr = jsonData[i].imgextra;
// console.log(jsonData[i].imgextra);
}else{
listArr.push(jsonData[i]);
// console.log(jsonData[i].imgsrc);
}
}
//更新狀態機
this.setState({
//頭部數據源
headerDataArr:headArr,
//cell的數據源
dataSource:this.state.dataSource.cloneWithRows(listArr)
});
})
//異常處理:網絡異常,請求異常
.catch((error) => {
console.error(error);
}
)}
const styles = StyleSheet.create({
headerViewStyle:{
// height:80,
// backgroundColor:'red'
},
cellStyle:{
flexDirection:'row',
borderBottomColor:'gray',
borderBottomWidth:0.5,
padding:10
},
rightViewStyle:{
marginLeft:20
},
imageStyle:{
width:90,
height:90
},
rightTextStyle:{
width:250,
fontSize:16,
paddingTop:10
},
bottomTextStyle:{
color:'gray',
bottom:-30,
// marginRight:40
left:170
}
});
//輸出獨立的類
module.exports = homeModel;
CJWNewsDetail.js:新聞詳情頁面
var newDetail = React.createClass({
//UI的布局函數
render(){
return(
<WebView
automaticallyAdjustContentInsets={false}
style={styles.webView}
//??????從上一頁面傳遞的data模型參數
source={{uri: this.props.data.url_3w}}
javaScriptEnabled={true}
domStorageEnabled={true}
decelerationRate="normal"
onNavigationStateChange={this.onNavigationStateChange}
onShouldStartLoadWithRequest={this.onShouldStartLoadWithRequest}
startInLoadingState={true}
scalesPageToFit={this.state.scalesPageToFit}
/>
);
},
});
三、項目實戰開始:
問題1:
圖1
遇到的問題::
Unable to find this module in its module map or any of the node_modules directories under /Users/chengjinwei/Desktop/RN實戰項目/RNProject/Component/Mine/RNMain and its parent directories
問題的分析:導入的文件模塊路徑出錯(在模塊映射或任何node_modules目錄下都無法找到該模塊’)
解決問題:var RNMain = require('./Component/Mine/RNMain');改為
var RNMain = require('./Component/Main/RNMain')即可;
問題2:
屏幕快照 2016-10-12 下午6.59.12.png
2-1webstorm里面編寫好程序之后,使用xcode跑起來之后,圖標沒有顯示出來,在xcode里面的圖片的存在有問題。
2-2處理:新建一個image.xcassets(在iOS->Resource->Asset Catalog->更改文件的名字-將圖片資源放到這個文件里面).??AppIcon 和LaunchImage不能少
導入TabNavigator :??是從外部導入的組件
1.找到工程路徑:cd+項目路徑
2.命令行導入navigator組件:npm install react-native-tab-navigator --save
屏幕快照 2016-10-11 下午7.03.02.png
項目框架搭建:
效果圖:
rn.gif
index.ios.js代碼:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View} from 'react-native';
var RNMain = require('./Component/Main/RNMain');
var RNProject = React.createClass({
render() {
return (
<RNMain/>
);
}
})
AppRegistry.registerComponent('RNProject', () => RNProject);
RNMain.js代碼:
import React, { Component } from 'react';
import { AppRegistry, StyleSheet, Text, View, Image, Navigator} from 'react-native';
//??是從外部導入的組件
import TabNavigator from 'react-native-tab-navigator';
// 導入文件的路徑
var Home = require('../Home/RNHome');
var Shop = require('../Shop/RNShop');
var Mine = require('../Mine/RNMine');
var More = require('../More/RNMore');
var Main = React.createClass({
getInitialState(){
return{
selectedTab:'home'
}
},
//UI的布局函數
render(){
return(
<TabNavigator>
{/*首頁*/}
{this.renderNavigatorFunction('首頁','icon_tabbar_homepage','icon_tabbar_homepage_selected','home','首頁',Home)}
{/*購物*/}
{this.renderNavigatorFunction('商家','icon_tabbar_merchant_normal','icon_tabbar_merchant_selected','shop','商家',Shop)}
{/*我的*/}
{this.renderNavigatorFunction('我的','icon_tabbar_mine','icon_tabbar_mine_selected','mine','我的',Mine)}
{/*更多*/}
{this.renderNavigatorFunction('更多','icon_tabbar_misc','icon_tabbar_misc_selected','more','更多',More)}
</TabNavigator>
);
},
// 對navigator封裝
renderNavigatorFunction(title,defaultImage,selectedImage,selectedItem,routeTitle,component){
return(
<TabNavigator.Item
title={title}
renderIcon={() => <Image source={{uri:defaultImage}} style={styles.iconStyle}/>}
renderSelectedIcon={() => <Image source={{uri:selectedImage}} style={styles.iconStyle}/>}
onPress={()=>this.setState({selectedTab:selectedItem})}
selected={this.state.selectedTab === selectedItem}
>
//導航組件
{/*<Home/>*/}
<Navigator
initialRoute={{name:routeTitle,component:component}}
configureScene={()=>{
return Navigator.SceneConfigs.PushFromRight;
}}
renderScene={(route,navigator)=>{
let Component = route.component;
return <Component {...route.passProps} navigator={navigator} />
}}
/>
</TabNavigator.Item>
)
}
});
const styles = StyleSheet.create({
containerStyle:{
flex:1,
justifyContent:'center',
alignItems:'center',
},
iconStyle:{
width:30,
height:30,
// backgroundColor:'red'
}
});
//輸出獨立的類
module.exports = Main;
RNHome.js代碼:
var HomeDetail = require('./RNHomeDetail');
var Home = React.createClass({
//UI的布局函數
render(){
return(
<View style={styles.containerStyle}>
{/*導航的點擊進入下一頁面*/}
<TouchableOpacity onPress={()=>{this.pushToDetail()}}>
<Text>
首頁
</Text>
</TouchableOpacity>
</View>
);
},
//導航的點擊進入下一頁面
pushToDetail(){
this.props.navigator.push(
{
//跳轉到指定的頁面
component:HomeDetail,
// 指定頁面的標題
title:'詳情頁'
}
)
}
});
const styles = StyleSheet.create({
containerStyle:{
flex:1,
justifyContent:'center',
alignItems:'center',
}
});
//輸出獨立的類
module.exports = Home;
RNHomeDetail.js代碼:
var HomeDetail = React.createClass({
//UI的布局函數
render(){
return(
<View style={styles.containerStyle}>
<TouchableOpacity onPress={()=>{this.popToBack()}}>
<Text>
詳情頁面
</Text>
</TouchableOpacity>
</View>
);
},
// 返回到上一頁面
popToBack(){
this.props.navigator.pop();
}
});
const styles = StyleSheet.create({
containerStyle:{
flex:1,
justifyContent:'center',
alignItems:'center',
backgroundColor:'red'
}
});
//輸出獨立的類
module.exports = HomeDetail;