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

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

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

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

這個時候進(jìn)入文件目錄中會看見:

工程簡介

2、打開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',
  },
 這里可以定義多個布局樣式:樣式名:{樣式設(shè)置},
如果定義多個樣式,要用“ ,”分隔
});
  • 視圖組件
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中不能返回多個View,但是可以在View中添加多個子視圖
  • 在不修改任何代碼的情況下運行:效果如下


    運行效果

3、添加導(dǎo)航欄

在React Native中,導(dǎo)航欄有兩種

  • Navigator,大部分的情況下使用這個,由facebook的react native團隊進(jìn)行開發(fā),一直在維護,同時支持iOS和安卓,由于在導(dǎo)航切換的時候需要進(jìn)行大量的加載,所以會占用JS線程較多時間。
  • NavigatorIOS,很少使用,由開源社區(qū)開發(fā),有很多bug,僅僅支持iOS。但是內(nèi)部由原生的UINavigationController實現(xiàn),所以實際運行的時候,和原生的iOS導(dǎo)航一樣,有一樣的動畫
    為了和本來導(dǎo)航欄動畫效果一致,所以使用NavigationIOS

之前又說到:要想使用必須先導(dǎo)入,所以要想使用NavigationIOS,必須現(xiàn)在import 中引入

NavigationIOS,

此時需要重寫下面代碼

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: '主頁',
          component: RootView,
        }}
      />
    );
  }
});
解析一下這些代碼的含義:
1.定義一個變量:DownloadDataShowListView,并初始化
2.返回一個導(dǎo)航欄:并設(shè)置樣式,標(biāo)題,和顯示界面

在上面代碼中compoent:為RootView,可是我們還沒有聲明,所以還需要寫上:

var RootView = React.createClass({
    render(){
      return (
        <Image source={require('./img/background.png')} style={styles.backgroundImg}>
          <Text style={styles.whiteText}>紙巾藝術(shù)</Text>
        </Image>
      );
    }
});
1.聲明一個RootView變量
2.返回一個圖片,在圖片中添加文字

flex布局

編輯完成后,save一次,在模擬器上按下command+R刷新:(如果看不到圖片重新啟動一次工程),便可看到下面效果:


顯示效果

4、下載網(wǎng)絡(luò)數(shù)據(jù)

使用Fetch進(jìn)行請求,關(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ò)請求,參數(shù)1:路徑 參數(shù)2:一些設(shè)置
method:請求方式
headers:請求頭
body:請求體

網(wǎng)絡(luò)是一個異步請求,所以,他返回的是一個Promise對象,這個對象有兩種處理方式:

  • 同步 then/catch
  • 異步 async/awiat

在結(jié)束最初渲染后(生命周期),加載數(shù)據(jù)。

componentDidMount() { this.downloadData(); }

把請求數(shù)據(jù)封裝成為一個方法

dwonloadData(){
      fetch(URL)
        .then((response) => response.json())
        .then((responseData) => {
          console.log(responseData);
        })
        .done();
    },
1、URL 是一個全局變量
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ò)下載回來的數(shù)據(jù)保存起來

getInitialState:function(){
      return{
        loaded:false,
        users:new ListView.DataSource({
          rowHasChanged:(row1,row2) => row1 !== row2,
        }),
      };
    },
line 1.系統(tǒng)函數(shù) 會自動調(diào)用一次
line 3.設(shè)置一個屬性 類型boolean 值false
line 4.設(shè)置一個屬性作為ListView的數(shù)據(jù)源
line 5.判斷兩個值相不相等

然后修改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ò)請求
line 3.轉(zhuǎn)成JSON數(shù)據(jù)格式
line 4-9.得到數(shù)據(jù)把、數(shù)據(jù)存好
line 10.完成

this.setState會觸發(fā)render重新調(diào)用,進(jìn)行重繪

.
.
有了數(shù)據(jù)源自然要創(chuàng)建ListView
LlistView需要的東西:

  • dataSource,一個簡單數(shù)組來描述MVC中的model,類似于iOS中的dataSource
  • renderRow,返回一個視圖組建.類似于iOS中的cellForRowAtIndexPath
  • renderSeparator,一般也需要這個方法,來說生成一個分隔線
    這個時候我們進(jìn)行判斷

創(chuàng)建一個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.加載一個背景圖片
line 4.在圖片上加載一個ListView

.

我們知道下載網(wǎng)絡(luò)數(shù)據(jù)需要時間,所以我們在添加一個loadingView

.
.

創(chuàng)建一個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. 加載一個背景圖片
line 4. 在圖片上添加一個loading動畫控件

.
.
現(xiàn)在我們只需要在render方法中判斷有沒有下載完數(shù)據(jù),分別顯示就好

render(){
       if (!this.state.loaded) {
          return this.renderLoadingView()
       }else{
          return this.renderListView()
       }
    },
line 1.渲染
line 2.對加載完成進(jìn)行判斷
line 3.加載中
line 4.否則
line 5.加載完成

.
.
在上面的代碼中,我們ListView的row是這樣子設(shè)置的:

renderRow={this.renderRow}
所以我們要去實現(xiàn)這個方法
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.一個點擊事件
line 4.設(shè)置了點擊事件的方法,帶參數(shù)
line 5.按下時的顏色
line 6.創(chuàng)建一個View座位TouchableHighlight的子視圖
line 7.創(chuàng)建一個View的子視圖Text,顯示數(shù)據(jù)
line 8.創(chuàng)建一個View的子視圖Text,顯示數(shù)據(jù)
...后面的就沒啥了

6、導(dǎo)航到第二個頁面

  • 你得有第二個頁面是不是?。?!
    創(chuàng)建第二個頁面:
//添加一個二級頁面
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.定義一個變量,二級頁面
line 2.渲染
line 3.返回
line 4.創(chuàng)建一個View
line 5.在View上添加一個子視圖Text
line 6.在View上添加一個子視圖Text
  • 有了第二個頁面,現(xiàn)在就差導(dǎo)航過去
    修改rowClicked方法
rowClicked(user){
      console.log(user);

      this.props.navigator.push({
        title:"我是第二個頁面",
        component:SecondPage,
        passProps:{user:user},
      })
    },
line 1.函數(shù)名
line 2.打印user信息
line 3.調(diào)用NavigationIOS的push方法
line 4.title:第二個頁面的標(biāo)題 等于self.title
line 5.component:到哪里去
line 6.passProps:傳參數(shù)

最后一句話:

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

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

demo地址

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

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

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