IOS React-native工程-請(qǐng)求網(wǎng)絡(luò)數(shù)據(jù)顯示并可進(jìn)入二級(jí)頁(yè)面(NavigationIOS,listView,ActivityIndicatorIOS,TouchableHighlight...)

1、創(chuàng)建一個(gè)工程

打開(kāi)終端 cd 到你想創(chuàng)建項(xiàng)目的目錄,然后執(zhí)行

react-native init DownloadDataShowListView
出現(xiàn)這個(gè)就安裝完了

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

工程簡(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è)圖片,在圖片中添加文字

flex布局

編輯完成后,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ù)

最后一句話:

這里只上傳了index.ios.js 以及 img文件夾

下載回來(lái)只需要把index.ios.js替換并且把img文件夾拖入文件夾中即可

demo地址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容