1、創(chuàng)建一個(gè)工程
打開(kāi)終端 cd 到你想創(chuàng)建項(xiàng)目的目錄,然后執(zhí)行
react-native init DownloadDataShowListView

這個(gè)時(shí)候進(jìn)入文件目錄中會(huì)看見(jiàn):

2、打開(kāi)index.ios.js
- 導(dǎo)入模塊
import {
...
這里是導(dǎo)入的模塊,必須先導(dǎo)入才能使用:比如要是使用Text,必須在這里先導(dǎo)入
} from 'react-native';
- 布局樣式:
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#F5FCFF',
},
這里可以定義多個(gè)布局樣式:樣式名:{樣式設(shè)置},
如果定義多個(gè)樣式,要用“ ,”分隔
});
- 視圖組件
class DownloadDataShowListView extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
},
在return中不能返回多個(gè)View,但是可以在View中添加多個(gè)子視圖
-
在不修改任何代碼的情況下運(yùn)行:效果如下
運(yùn)行效果
3、添加導(dǎo)航欄
在React Native中,導(dǎo)航欄有兩種
- Navigator,大部分的情況下使用這個(gè),由facebook的react native團(tuán)隊(duì)進(jìn)行開(kāi)發(fā),一直在維護(hù),同時(shí)支持iOS和安卓,由于在導(dǎo)航切換的時(shí)候需要進(jìn)行大量的加載,所以會(huì)占用JS線程較多時(shí)間。
- NavigatorIOS,很少使用,由開(kāi)源社區(qū)開(kāi)發(fā),有很多bug,僅僅支持iOS。但是內(nèi)部由原生的UINavigationController實(shí)現(xiàn),所以實(shí)際運(yùn)行的時(shí)候,和原生的iOS導(dǎo)航一樣,有一樣的動(dòng)畫(huà)
為了和本來(lái)導(dǎo)航欄動(dòng)畫(huà)效果一致,所以使用NavigationIOS
之前又說(shuō)到:要想使用必須先導(dǎo)入,所以要想使用NavigationIOS,必須現(xiàn)在import 中引入
NavigationIOS,
此時(shí)需要重寫(xiě)下面代碼
class DownloadDataShowListView extends Component {
render() {
return (
<View style={styles.container}>
<Text style={styles.welcome}>
Welcome to React Native!
</Text>
<Text style={styles.instructions}>
To get started, edit index.ios.js
</Text>
<Text style={styles.instructions}>
Press Cmd+R to reload,{'\n'}
Cmd+D or shake for dev menu
</Text>
</View>
);
}
}
替換為:
var DownloadDataShowListView = React.createClass({
render: function() {
return (
<NavigatorIOS
style={styles.container}
initialRoute={{
title: '主頁(yè)',
component: RootView,
}}
/>
);
}
});
解析一下這些代碼的含義:
1.定義一個(gè)變量:DownloadDataShowListView,并初始化
2.返回一個(gè)導(dǎo)航欄:并設(shè)置樣式,標(biāo)題,和顯示界面
在上面代碼中compoent:為RootView,可是我們還沒(méi)有聲明,所以還需要寫(xiě)上:
var RootView = React.createClass({
render(){
return (
<Image source={require('./img/background.png')} style={styles.backgroundImg}>
<Text style={styles.whiteText}>紙巾藝術(shù)</Text>
</Image>
);
}
});
1.聲明一個(gè)RootView變量
2.返回一個(gè)圖片,在圖片中添加文字
編輯完成后,save一次,在模擬器上按下command+R刷新:(如果看不到圖片重新啟動(dòng)一次工程),便可看到下面效果:

4、下載網(wǎng)絡(luò)數(shù)據(jù)
使用Fetch進(jìn)行請(qǐng)求,關(guān)于Fetch文檔
fetch('https://mywebsite.com/endpoint/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
firstParam: 'yourValue',
secondParam: 'yourOtherValue',
})
})
調(diào)用網(wǎng)絡(luò)請(qǐng)求,參數(shù)1:路徑 參數(shù)2:一些設(shè)置
method:請(qǐng)求方式
headers:請(qǐng)求頭
body:請(qǐng)求體
網(wǎng)絡(luò)是一個(gè)異步請(qǐng)求,所以,他返回的是一個(gè)Promise對(duì)象,這個(gè)對(duì)象有兩種處理方式:
- 同步 then/catch
- 異步 async/awiat
在結(jié)束最初渲染后(生命周期),加載數(shù)據(jù)。
componentDidMount() { this.downloadData(); }
把請(qǐng)求數(shù)據(jù)封裝成為一個(gè)方法
dwonloadData(){
fetch(URL)
.then((response) => response.json())
.then((responseData) => {
console.log(responseData);
})
.done();
},
1、URL 是一個(gè)全局變量
var URL = 'https://raw.githubusercontent.com/LeoMobileDeveloper/React-Native-Files/master/person.json';
2、then 同步
3、.done()完成
輸出結(jié)果如下
[ { nickname: 'Leo', realname: 'WenchenHuang' },
{ nickname: 'Jack', realname: 'SomethingElse' } ]
5、顯示到ListView中
要顯示到ListView中我們要把從網(wǎng)絡(luò)下載回來(lái)的數(shù)據(jù)保存起來(lái)
getInitialState:function(){
return{
loaded:false,
users:new ListView.DataSource({
rowHasChanged:(row1,row2) => row1 !== row2,
}),
};
},
line 1.系統(tǒng)函數(shù) 會(huì)自動(dòng)調(diào)用一次
line 3.設(shè)置一個(gè)屬性 類(lèi)型boolean 值false
line 4.設(shè)置一個(gè)屬性作為L(zhǎng)istView的數(shù)據(jù)源
line 5.判斷兩個(gè)值相不相等
然后修改downloadData方法:
dwonloadData(){
fetch(URL)
.then((response) => response.json())
.then((responseData) => {
this.setState({
users:this.state.users.cloneWithRows(responseData),
loaded:true,
});
})
.done();
},
line 1.函數(shù)名
line 2.網(wǎng)絡(luò)請(qǐng)求
line 3.轉(zhuǎn)成JSON數(shù)據(jù)格式
line 4-9.得到數(shù)據(jù)把、數(shù)據(jù)存好
line 10.完成
this.setState會(huì)觸發(fā)render重新調(diào)用,進(jìn)行重繪
.
.
有了數(shù)據(jù)源自然要?jiǎng)?chuàng)建ListView
LlistView需要的東西:
- dataSource,一個(gè)簡(jiǎn)單數(shù)組來(lái)描述MVC中的model,類(lèi)似于iOS中的dataSource
- renderRow,返回一個(gè)視圖組建.類(lèi)似于iOS中的cellForRowAtIndexPath
- renderSeparator,一般也需要這個(gè)方法,來(lái)說(shuō)生成一個(gè)分隔線
這個(gè)時(shí)候我們進(jìn)行判斷
創(chuàng)建一個(gè)ListView
renderListView(){
return(
<Image source={require('./img/background.png')} style={styles.backgroundImg}>
<ListView
dataSource={this.state.users}
renderRow={this.renderRow}
style={styles.fullList}
renderSeparator={(sectionID, rowID) => <View key={`${sectionID}-${rowID}`} style={styles.separator} />}
/>
</Image>
);
},
line 1.函數(shù)名
line 3.加載一個(gè)背景圖片
line 4.在圖片上加載一個(gè)ListView
.
我們知道下載網(wǎng)絡(luò)數(shù)據(jù)需要時(shí)間,所以我們?cè)谔砑右粋€(gè)loadingView
.
.
創(chuàng)建一個(gè)loadingView
renderLoadingView(){
return(
<Image source={require('./img/background.png')} style={styles.backgroundLoading}>
<ActivityIndicatorIOS
style={{alignItems:'center',justifyContent:'center',height:50}}
size= "large"
color= "red"
/>
</Image>
);
},
line 1.函數(shù)名
line 3. 加載一個(gè)背景圖片
line 4. 在圖片上添加一個(gè)loading動(dòng)畫(huà)控件
.
.
現(xiàn)在我們只需要在render方法中判斷有沒(méi)有下載完數(shù)據(jù),分別顯示就好
render(){
if (!this.state.loaded) {
return this.renderLoadingView()
}else{
return this.renderListView()
}
},
line 1.渲染
line 2.對(duì)加載完成進(jìn)行判斷
line 3.加載中
line 4.否則
line 5.加載完成
.
.
在上面的代碼中,我們ListView的row是這樣子設(shè)置的:
renderRow={this.renderRow}
所以我們要去實(shí)現(xiàn)這個(gè)方法
renderRow(user){
return (
<TouchableHighlight
onPress={() => this.rowClicked(user)}
underlayColor = '#ddd'>
<View style={styles.rightCongtainer}>
<Text style={styles.whiteText}>{user.nickname}</Text>
<Text style={styles.whiteText}>{user.realname}</Text>
</View>
</TouchableHighlight>
);
},
line 1.函數(shù)名
line 3.一個(gè)點(diǎn)擊事件
line 4.設(shè)置了點(diǎn)擊事件的方法,帶參數(shù)
line 5.按下時(shí)的顏色
line 6.創(chuàng)建一個(gè)View座位TouchableHighlight的子視圖
line 7.創(chuàng)建一個(gè)View的子視圖Text,顯示數(shù)據(jù)
line 8.創(chuàng)建一個(gè)View的子視圖Text,顯示數(shù)據(jù)
...后面的就沒(méi)啥了
6、導(dǎo)航到第二個(gè)頁(yè)面
- 你得有第二個(gè)頁(yè)面是不是?。。?br> 創(chuàng)建第二個(gè)頁(yè)面:
//添加一個(gè)二級(jí)頁(yè)面
var SecondPage = React.createClass({
render(){
return(
<View style={styles.container}>
<Text style={styles.blackText}>{this.props.user.nickname}</Text>
<Text style={styles.blackText}>{this.props.user.realname}</Text>
</View>
);
}
});
line 1.定義一個(gè)變量,二級(jí)頁(yè)面
line 2.渲染
line 3.返回
line 4.創(chuàng)建一個(gè)View
line 5.在View上添加一個(gè)子視圖Text
line 6.在View上添加一個(gè)子視圖Text
- 有了第二個(gè)頁(yè)面,現(xiàn)在就差導(dǎo)航過(guò)去
修改rowClicked方法
rowClicked(user){
console.log(user);
this.props.navigator.push({
title:"我是第二個(gè)頁(yè)面",
component:SecondPage,
passProps:{user:user},
})
},
line 1.函數(shù)名
line 2.打印user信息
line 3.調(diào)用NavigationIOS的push方法
line 4.title:第二個(gè)頁(yè)面的標(biāo)題 等于self.title
line 5.component:到哪里去
line 6.passProps:傳參數(shù)
最后一句話:
