時間過得真快,眨眼已經(jīng)快3年了!
1.我的第一個App
還記得我14年初寫的第一個iOS小程序,當時是給別人寫的一個單機的相冊,也是我開發(fā)的第一個完整的app,雖然功能挺少,但是耐不住心中的激動啊,現(xiàn)在我開始學react native,那么現(xiàn)在對于react native也算是有所了解了,就用網(wǎng)上的接口開發(fā)一個小程序,現(xiàn)在帶大家來寫這個程序!接口是用看知乎的API,簡簡單單的只有g(shù)et,可以從這里入門,也算是帶大家入門吧,過后我會把源代碼放在我的github上,前期項目肯定特別簡陋,后面慢慢來優(yōu)化,好了,廢話不多說,坐穩(wěn)扶好,咱們開車了?。。。。?br> 首先需要一個框架,可以省時省力,不再重復的造輪子。
(1)框架
框架咱們就不再搭建了,我前面寫了一個特別簡單的框架,放在github上了,咱們直接下載下來用就可以了,下載地址在我的github上,這個框架是基于react-native-tab-navigator的,運行這個程序,咱們做的第一步就是打開終端配置環(huán)境
$npm install
$npm install react-native-tab-navigator --save
然后我們就可以打開文件運行程序了
(2)修改名稱
用Xcode打開文件navtabbar.xcodeproj,進入AppDelegate.m文件中把
RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
moduleName:@"navtabbar"
initialProperties:nil
launchOptions:launchOptions];
中的moduleName改為你想要的名字,然后在plist文件中修改Bundle name為你修改過的名字,最后最重要的一步,打開index.ios.js文件修改注冊入口,
AppRegistry.registerComponent('你修改的名字', () => NavIndex)
現(xiàn)在iOS的App名稱修改完成,可以運行一下看看是不是修改成功!
2.首頁搭建
(1)首頁界面代碼修改
進入login.js文件,刪除 <Text onPress={this._onPage.bind(this)} style={styles.textStyle}>登錄</Text>
然后添加Image,咱們待會給首頁設(shè)置一個背景圖,添加
TouchableOpacity,
Dimensions,
TextInput
OK,添加這些組件就夠了!
(2)界面搭建
首先,我們先在src文件夾中新建一個images的文件夾,用于存放我們的圖片
現(xiàn)在就可以找一些圖片存進去。
<Image source={require('./images/background.jpg')} style={styles.backgroundStyle}>
然后簡單的登錄一下,當然只是一個界面而已
<FormText style={{marginTop:60}}
placeholder='賬號'
placeholderTextColor='gray'
defaultValue='Demon404'
/>
<FormText style={{marginTop:10}}
placeholder='請輸入密碼'
placeholderTextColor='orange'
defaultValue=''
/>
<TouchableOpacity onPress={this._onPage.bind(this)}>
<Button style={{marginTop:20,width:Width/2,height:40,backgroundColor:'blue',borderRadius:10}}
buttonTitle="登錄"
/>
</TouchableOpacity>
這里的FormText是我自己寫的一個小控件。
下面可以看一下界面效果

由于沒有post請求,所以這個頁面大家就簡單的樂呵樂呵就好了,反正下個頁面跟這個頁面沒什么太大關(guān)系.......
(3)主頁搭建
主頁就是一個Tabbar界面,目前考慮先有三個模塊!,日后再考慮刪減,嗯,就是這么任性!
一個是推送的文章模塊,一個是搜索模塊,最后的是設(shè)置模塊。
咱們先看文章模塊主頁面
cellRow(data) {
return (
<View style={styles.cellStyle}>
<Image style={{width:WIDTH-40, height: 100}}
source={{uri: data.pic}}
/>
<Text style={styles.title}>{data.excerpt}</Text>
</View>
);
}
render() {
return (
<View style={styles.container}>
<NavBar name='看知乎'/>
<ListView
initiaListSize={1}
onEndReachedThreshold={10}
dataSource={this.state.dataSource}
renderRow={this.cellRow.bind(this)}
style={styles.listView}
/>
</View>
);
}
這是我們的ListView頁面的代碼,只是簡單的抓取看知乎的一個接口頁面,
怎么實現(xiàn)數(shù)據(jù)同步呢?
這就要說到組件的生命周期了:一般來說,一個組件類由 extends Component
創(chuàng)建,并且提供一個 render
方法以及其他可選的生命周期函數(shù)、組件相關(guān)的事件或方法來定義。
咱們這里簡單說一下生命周期函數(shù)
componentWillMount:只會在裝載之前調(diào)用一次,在 render
之前調(diào)用
componentDidMount:只會在裝載完成之后調(diào)用一次,在 render
之后調(diào)用
componentWillUnmount: 卸載組件時調(diào)用,
constructor(props, context):構(gòu)造函數(shù),在創(chuàng)建組件的時候調(diào)用一次
目前使用的也就這幾個,當然聲明周期所調(diào)用的函數(shù)不僅僅這幾個,這些咱們?nèi)蘸笤僦v。
在這里,我們簡單的用到了componentDidMount,
首先var GET_URL = 'http://api.kanzhihu.com/getposts';
然后在listView頁面定義數(shù)據(jù)解析方法
componentDidMount(){this.fetchData();}
實現(xiàn):
fetchData(){
fetch(GET_URL)
//ES6的寫法左邊代表輸入的參數(shù)右邊是邏輯處理和返回結(jié)果
.then((response) => response.json())
.then((responseData) => {
this.setState({
dataSource : this.state.dataSource.cloneWithRows(responseData.posts),
});
})
.done();
}
constructor(props) {
super(props);//state內(nèi)部維護的一個狀態(tài),我們剛開始進來的為空,來加載空的view
this.state = {dataSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2,}),};
}
然后根據(jù)上面的RowData就可以實現(xiàn)下面的頁面效果


圖1就是咱們搭建的主頁,圖2是詳細頁。
圖1和圖2實現(xiàn)原理是相同的,都是用listView來搭建頁面,那么如何來傳值呢?
Nav 有個屬性renderScene 回調(diào)方法有兩個參數(shù)route和navigator。
大家還記得{...route.params}吧,
咱們需要做的就是在第一個頁面push到第二個頁面的時候這樣寫
this.props.navigator.push({
component:Detail,
params:{nextdata: rowdata},
})
第二個頁面直接寫this.props.nextdata就可以調(diào)用傳過去的rowdata了,那么第二個頁面實現(xiàn)起來還難嗎?這里就不在多說了,
ps:大家可以想一下renderRow={this.cellRow.bind(this)}為什么要這么寫?當初renderRow={this.cellRow()}不也可以嗎?
(4)搜索頁搭建
咱么先來看圖吧,這個模塊暫時實現(xiàn)了兩個頁面的功能,以后慢慢添加,不著急....


這就是那兩個頁面,也非常簡單,我就把思路說一下,大家可以想著做就行了,程序猿嘛,多動腦還是很好的!,一看就知道,搜索頁就是幾個簡單的UI,然后出發(fā)幾個方法,這里我是在搜索頁把接口傳到下一頁了,這個其實不推薦,主要是我為了省代碼,并且搜索名稱和排行榜搜索的接口不太一樣,大家理解就行,
首先,搜索框這里我用了textinput來代替,其實功能也是一樣的。點擊放大鏡,把輸入框里的內(nèi)容拼接到接口上,傳到下一頁,下一頁直接用收到的接口解析就可以了,那么怎么得到textinput里面的值呢?
來看代碼
<TextInput
style={styles.inputStyle}
placeholder="請輸入搜索條件!"
onChangeText={(text) => this.setState({text})}
/>
constructor(props) {
super(props);
this.state = {text: ''};
}
searchUser(){
console.log(this.state.text);
看過文檔的朋友應(yīng)該都知道onChangeText的作用是干嘛的,我也不多說,那么列表頁也如同前幾個頁面一樣,一通則百通。
3.最后
把完整的gif圖放給大家 ??O(∩∩)O哈哈O(∩∩)O哈哈~

4.總結(jié)
其實這些都非常簡單,從頭到尾都沒用太難的東西,從登錄頁開始,咱么搭建了賬號和密碼的輸入框,以及頭像和登錄按鈕,這些基礎(chǔ)的UI對大家來說肯定不是問題,對新手來說應(yīng)該問題也不大,使用控件,設(shè)置一下屬性,控制一下位置,這個頁面一點數(shù)據(jù)都沒有用到。接下來進入首頁,通過組件生命周期函數(shù),咱么解析下來的數(shù)據(jù)綁定到ListView上面,然后在把需要的字段傳遞到下一頁,下一頁通過拼接的接口解析數(shù)據(jù),展現(xiàn)給大家,中間還加了一個WebView,因為具體的接口沒有,所以暫時就通過查詢到的數(shù)據(jù)直接把網(wǎng)頁展現(xiàn)給大家,item圖標暫時也沒有換,這個App暫時只有這些,缺失的東西以后慢慢添加,功能模塊也慢慢添加,這里大概的框架也給大家分享了,大家可以自由發(fā)揮....另外代碼有些需要簡化修改,這些我會慢慢來,
這里我把github上的源碼地址給大家分享一下,也歡迎大家指出有錯誤的地方,共同學習,努力提高!
Demon404的github:https://github.com/Demon404/KZHApp
由于引入了react-native-tab-navigator,所以一定要加上去才能運行
install react-native-tab-navigator --save,
本文原創(chuàng),首發(fā)地點為博客園