React Native從零開始(八)ListView網絡獲取數據(Fetch)顯示
先上效果圖:
一、思路
實現這個效果,我們需要了解ListView的實現和Fetch的實現方法,並將其結合,這兩個知識點在前兩篇博客中已經有寫到,其實沒有什麼難點,也可以加上頁面等待時的一個效果,在數據未加載完成時我們可以顯示Text,提示正在下載
二、實現
1、我們需要設置State來存儲數據的狀態,在未下載完成時爲false完成時則設置成true
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged:(oldRow,newRow) => oldRow!==newRow
});
this.state = {
/*1設置初始值*/
loaded: false,
dataSource:ds
};
}
這個時候創建一個DataSource來判斷這兩行是否相同,就是是否發生變化,決定渲染哪些行組件,避免全部渲染,提高渲染效率。
2、創建一個方法來實現數據的下載
//下載數據
getData() {
fetch(REQUEST_URL)
.then((response) => {
return response.json();
})
.then((responseData) => {
this.setState({
loaded:true,
dataSource:this.state.dataSource.cloneWithRows(responseData.movies)
});
})
}
這裏第二個then的話是數據下載成功,我們將state的值重新賦值,然後將下載的數據克隆,是的dataSource不使用原數據。
3、使用componentDidMount方法來執行數據的下載,這個方法是在組件掛載後開始執行的
//組件掛載完成後執行的方法
componentDidMount(){
//組件掛載後開始下載數據
this.getData();
}
4、渲染ListView的頭部、行、和分割線
//渲染行組件
function _renderRow(movie){
return(
<View style={styles.row}>
<Image
style={styles.thumbnail}
source={{uri:movie.posters.thumbnail}}/>
<View >
<Text >{movie.title}</Text>
<Text >{movie.year}</Text>
</View>
</View>
);
}
//渲染頭部
function _renderHeader(){
return(
<View >
<Text >Movies List</Text>
<View ></View>
</View>
);
}
//渲染分割線
function _renderSeparator(sectionId,rowId){
return(
<View
style={styles.separator}
key={sectionId+rowId}></View>
);
}
5、根據state的不同的值來渲染不同的控件
render(){
/*2如果未請求到數據提示等待加載,如果請求到數據顯示
* */
//加載前
if(!this.state.loaded){
return LoadingView();
}
//加載後
return (
<ListView
style={styles.listView}
dataSource={this.state.dataSource}
renderRow={_renderRow}
renderHeader={_renderHeader}
renderSeparator={_renderSeparator}
initialListSize={10}
/>
);
}
6、在index頁面調用這個控件就好
var MyListView = require("./MyView/MyListView");
export default class MovieListView extends Component {
render() {
return (
<MyListView/>
);
}
}
三、最後附上所有代碼
MyListView.js
/**
* Created by 11158 on 2017-01-17.
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View,
Image,
ListView
} from 'react-native';
var REQUEST_URL = "https://raw.githubusercontent.com/facebook/react-native/master/docs/MoviesExample.json";
/*
邏輯:未獲取數據時,顯示等待頁面;獲得數據時,顯示電影列表頁面
需要用到state的屬性,用於記錄下載狀態
* */
//未下載完數據顯示的頁面
function LoadingView() {
return (
<View style={styles.loadingContainer}>
<Text style={styles.loadingText}>Loading Movies......</Text>
</View>
);
}
//渲染行組件
function _renderRow(movie){
return(
<View style={styles.row}>
<Image
style={styles.thumbnail}
source={{uri:movie.posters.thumbnail}}/>
<View >
<Text >{movie.title}</Text>
<Text >{movie.year}</Text>
</View>
</View>
);
}
//渲染頭部
function _renderHeader(){
return(
<View >
<Text >Movies List</Text>
<View ></View>
</View>
);
}
//渲染分割線
function _renderSeparator(sectionId,rowId){
return(
<View
style={styles.separator}
key={sectionId+rowId}></View>
);
}
class MyListView extends Component{
constructor(props){
super(props);
var ds = new ListView.DataSource({
rowHasChanged:(oldRow,newRow) => oldRow!==newRow
});
this.state = {
/*1設置初始值*/
loaded: false,
dataSource:ds
};
}
//組件掛載完成後執行的方法
componentDidMount(){
//組件掛載後開始下載數據
this.getData();
}
//下載數據
getData() {
fetch(REQUEST_URL)
.then((response) => {
return response.json();
})
.then((responseData) => {
this.setState({
loaded:true,
dataSource:this.state.dataSource.cloneWithRows(responseData.movies)
});
})
}
render(){
/*2如果未請求到數據提示等待加載,如果請求到數據顯示
* */
//加載前
if(!this.state.loaded){
return LoadingView();
}
//加載後
return (
<ListView
style={styles.listView}
dataSource={this.state.dataSource}
renderRow={_renderRow}
renderHeader={_renderHeader}
renderSeparator={_renderSeparator}
initialListSize={10}
/>
);
}
}
const styles = StyleSheet.create({
//loading樣式
loadingContainer:{
flex:1,
marginTop:25,
backgroundColor:"cyan",
justifyContent:"center",
alignItems:"center"
},
loadingText:{
fontSize:30,
fontWeight:"bold",
textAlign:"center",
marginLeft:10
,marginRight:10
},
//行樣式
row:{
flexDirection:"row",
padding:5,
alignItems:"center",
backgroundColor:"#F5FCFF"
},
//圖片樣式
thumbnail:{
width:53,
height:81,
backgroundColor:"gray"
},
//分割線樣式
separator:{
height:1,
backgroundColor:"black"
},
listView:{
marginTop:25,
backgroundColor:"#F5FCFF"
},
});
module.exports = MyListView;
index.android.js
/**
* Sample React Native App
* https://github.com/facebook/react-native
* @flow
*/
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
Text,
View
} from 'react-native';
var MyListView = require("./MyView/MyListView");
export default class MovieListView extends Component {
render() {
return (
<MyListView/>
);
}
}
const styles = StyleSheet.create({
});
AppRegistry.registerComponent('MovieListView', () => MovieListView);
大家可以加好友交流學習
QQ:1115856293
微信: