- 上次课程回顾
通过RN环境,配合View、Text、Image、TextInput、Button这些组件,可以实现简单的页面布局。
还可以通过StyleSheet控制显示的样式。
2、本次课程内容
2.1、FlatList的基本使用
FlatList类似Android中的ListView。
FlatList使用时,需要自定义每一行的内容,因此必须通过自己编写一个方法,来生成每一行的布局。
同时FlatList支持头部和尾部的自定义界面。
基本列表使用:
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */
import React, {Component} from 'react'; import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native'; import logo from './images/logo.png';
var {height, width} = Dimensions.get('window');
const styles = StyleSheet.create({ container : { flex:1, // 填充满整个屏幕 alignItems: 'center' // backgroundColor: "red" }, mainLine : { width:width - 20, backgroundColor: "red", flexDirection: 'row' }, lineId : { flex:1, fontSize: 30 , backgroundColor: "blue" }, lineTitle : { flex:2 , fontSize: 25 , backgroundColor: "yellow" } });
//const mainUrl = "https://gank.io/api/data/Android/10/" export default class App extends Component<Props> { constructor(props) { super(props); let arr = new Array(); for (let i = 0;i < 20;i++) { arr[i] = { key:i + "", title:'测试数据' + i }; }
this.state = { data:arr } }
_renderItem = ({item}) => { return ( <View style={styles.mainLine}> <Text style={styles.lineId}>{item.key}</Text> <Text style={styles.lineTitle}>{item.title}</Text> </View> ); }
render() { return ( <View style="styles.container"> <FlatList data={this.state.data} renderItem={this._renderItem} > </FlatList> </View> ); } } |
通过data属性设置要显示的数据,必须为数组类型,建议里面放入对象,对象中建议包含key属性,建议类型为 String。 还要通过renderItem方法来渲染每一行显示的格式,该属性建议自己编写一个方法来配合使用,方法中需要传入一个item参数,表示每一行的数据内容。 |
基于这个基本功能,我们可以加入一些扩展。
- 设置分割线
通过属性:ItemSeparatorComponent,来实现。
需要自定义一个方法,返回分割线的格式。
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */
import React, {Component} from 'react'; import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native'; import logo from './images/logo.png';
var {height, width} = Dimensions.get('window');
const styles = StyleSheet.create({ container : { flex:1, // 填充满整个屏幕 alignItems: 'center', // backgroundColor: "red" }, mainLine : { width:width - 20, alignItems: "center", height: 40, lineHeight: 40, flexDirection: 'row' }, lineId : { flex:1, fontSize: 25 , height: 40, backgroundColor: "blue" }, lineTitle : { flex:2 , fontSize: 25 , height: 40, backgroundColor: "yellow" } });
//const mainUrl = "https://gank.io/api/data/Android/10/" export default class App extends Component<Props> { constructor(props) { super(props); let arr = new Array(); for (let i = 0;i < 20;i++) { arr[i] = { key:i + "", title:'测试数据' + i }; }
this.state = { data:arr } }
_renderItem = ({item}) => { return ( <View style={styles.mainLine}> <Text style={styles.lineId}>{item.key}</Text> <Text style={styles.lineTitle}>{item.title}</Text> </View> ); }
_seperator = () => { return ( <View style={{width:width-20,height:2,backgroundColor:"green"}}/> ); }
render() { return ( <View style="styles.container"> <FlatList data={this.state.data} renderItem={this._renderItem} ItemSeparatorComponent={this._seperator} > </FlatList> </View> ); } } |
- 下拉刷新
onRefresh和refreshing两个值配合可以完成下拉刷新。
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */
import React, {Component} from 'react'; import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native'; import logo from './images/logo.png';
var {height, width} = Dimensions.get('window');
const styles = StyleSheet.create({ container : { flex:1, // 填充满整个屏幕 alignItems: 'center', // backgroundColor: "red" }, mainLine : { width:width - 20, alignItems: "center", height: 40, lineHeight: 40, flexDirection: 'row' }, lineId : { flex:1, fontSize: 25 , height: 40, backgroundColor: "blue" }, lineTitle : { flex:2 , fontSize: 25 , height: 40, backgroundColor: "yellow" } });
let arr = new Array(); for (let i = 0;i < 20;i++) { arr[i] = { key:i + "", title:'测试数据' + i }; }
//const mainUrl = "https://gank.io/api/data/Android/10/" export default class App extends Component<Props> { constructor(props) { super(props);
this.state = { data:arr , isRefresh :false } }
_renderItem = ({item}) => { return ( <View style={styles.mainLine}> <Text style={styles.lineId}>{item.key}</Text> <Text style={styles.lineTitle}>{item.title}</Text> </View> ); }
_seperator = () => { return ( <View style={{width:width-20,height:2,backgroundColor:"green"}}/> ); }
reloadData = () => { // 重新从网上查询数据,并替换到这里 // 重新设置isRefresh为false let newArr = new Array(); for (let i = 0;i < 20;i++) { newArr[i] = { key:1 + "", title:"新数据" + i } }
// Alert.alert(arr[0].title); this.setState({ data:newArr });
}
render() { return ( <View style="styles.container"> <FlatList data={this.state.data} renderItem={this._renderItem} onRefresh={this.reloadData} refreshing={this.state.isRefresh} ItemSeparatorComponent={this._seperator} > </FlatList> </View> ); } } |
- 上拉加载更多
必须通过分页的功能来每次加载下一页的内容。
每次划动到最下面,都加载新的20条数据。
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */
import React, {Component} from 'react'; import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native'; import logo from './images/logo.png';
var {height, width} = Dimensions.get('window');
const styles = StyleSheet.create({ container : { flex:1, // 填充满整个屏幕 alignItems: 'center', // backgroundColor: "red" }, mainLine : { width:width - 20, alignItems: "center", height: 40, lineHeight: 40, flexDirection: 'row' }, lineId : { flex:1, fontSize: 25 , height: 40, backgroundColor: "blue" }, lineTitle : { flex:2 , fontSize: 25 , height: 40, backgroundColor: "yellow" } });
let arr = new Array(); for (let i = 0;i < 20;i++) { arr[i] = { key:i + "", title:'测试数据' + i }; }
//const mainUrl = "https://gank.io/api/data/Android/10/" export default class App extends Component<Props> { constructor(props) { super(props); let allRows = 100; this.totalPage = Math.ceil(allRows / 20); this.state = { pageNo : 1, data:arr , isRefresh :false } }
_renderItem = ({item}) => { return ( <View style={styles.mainLine}> <Text style={styles.lineId}>{item.key}</Text> <Text style={styles.lineTitle}>{item.title}</Text> </View> ); }
_seperator = () => { return ( <View style={{width:width-20,height:2,backgroundColor:"green"}}/> ); }
reloadData = () => { // 重新从网上查询数据,并替换到这里 // 重新设置isRefresh为false let newArr = new Array(); for (let i = 0;i < 20;i++) { newArr[i] = { key:1 + "", title:"新数据" + i } }
// Alert.alert(arr[0].title); this.setState({ pageNo:1, data:newArr });
}
loadMoreData = () => { if (this.state.pageNo < this.totalPage) { this.state.pageNo ++ ; // 重新加载新的数据内容 let newArr = new Array(); for (let i = 0;i < 20;i++) { newArr[i] = { key : (i + (this.state.pageNo-1) * 20) + "", title : "更多数据" + (i + (this.state.pageNo-1) * 20) } } // 将原有数据和新数据组合到一起 let allData = this.state.data.concat(newArr); this.setState({ pageNo : this.state.pageNo , data:allData }); } }
_footerView = () => { if (this.state.pageNo < this.totalPage) { return ( <View style={{width:width-20,alignItems: 'center'}}> <Text style={{fontSize: 30,color: "red"}}>正在加载更多...</Text> </View> ); } else { return ( <View style={{width:width-20,alignItems: 'center'}}> <Text style={{fontSize: 30,color: "green"}}>没有更多数据了</Text> </View> ); } }
render() { return ( <View style="styles.container"> <FlatList data={this.state.data} renderItem={this._renderItem} onRefresh={this.reloadData} refreshing={this.state.isRefresh} ListFooterComponent={this._footerView} onEndReached={this.loadMoreData} onEndReachedThreshold={1} ItemSeparatorComponent={this._seperator} > </FlatList> </View> ); } } |
2.2、调用网络接口数据
这里使用一个现成的网络接口,返回JSON信息,实现分页列表显示数据的功能。
const mainUrl = https://gank.io/api/data/Android/10/ + pageNo
在ReactNative中,如果想调用网络数据接口,需要通过fetch方法来完成。
该方法传入以下参数:
url地址
一些参数信息,例如:method,headers,body
/** * Sample React Native App * https://github.com/facebook/react-native * * @format * @flow */
import React, {Component} from 'react'; import {ImageEditor,FlatList,TouchableOpacity,Alert,Button,Dimensions,StyleSheet,Text, TextInput,View,Image} from 'react-native'; import logo from './images/logo.png';
var {height, width} = Dimensions.get('window');
const styles = StyleSheet.create({ container : { flex:1, // 填充满整个屏幕 alignItems: 'center', // backgroundColor: "red" }, mainLine : { width:width - 20, alignItems: "center", flexDirection: 'row' }, lineId : { flex:1, fontSize: 25 , backgroundColor: "blue" }, lineTitle : { flex:2 , fontSize: 25 , backgroundColor: "yellow" } });
let arr = new Array(); for (let i = 0;i < 20;i++) { arr[i] = { key:i + "", title:'测试数据' + i }; }
const mainUrl = "https://gank.io/api/data/Android/10/" export default class App extends Component<Props> { constructor(props) { super(props); let allRows = 100; this.totalPage = Math.ceil(allRows / 10); this.state = { pageNo : 1, data:[] , isRefresh :false }; this.fetchData(); }
fetchData = () => { // 读取远程数据 fetch(mainUrl + this.state.pageNo,{ method:"GET" }).then((response) => response.json()) .then((jsonObj) => { // 接收到结果后的处理 // 循环结果,将结果内容放到data数组中 let newArr = new Array(); for (let i = 0;i < jsonObj.results.length;i++) { let {_id,desc} = jsonObj.results[i]; newArr[i] = { key : _id, title : desc } } let allData = this.state.data.concat(newArr); this.setState({ pageNo:this.state.pageNo , data:allData }); }).done() ; }
_renderItem = ({item}) => { return ( <View style={styles.mainLine}> <Text style={styles.lineId}>{item.key}</Text> <Text style={styles.lineTitle}>{item.title}</Text> </View> ); }
_seperator = () => { return ( <View style={{width:width-20,height:2,backgroundColor:"green"}}/> ); }
reloadData = () => { // 重新从网上查询数据,并替换到这里 // 重新设置isRefresh为false
// Alert.alert(arr[0].title); this.setState({ pageNo:1, data:[] }); this.fetchData();
}
loadMoreData = () => { if (this.state.pageNo < this.totalPage) { this.state.pageNo ++ ; this.fetchData(); } }
_footerView = () => { if (this.state.pageNo < this.totalPage) { return ( <View style={{width:width-20,alignItems: 'center'}}> <Text style={{fontSize: 30,color: "red"}}>正在加载更多...</Text> </View> ); } else { return ( <View style={{width:width-20,alignItems: 'center'}}> <Text style={{fontSize: 30,color: "green"}}>没有更多数据了</Text> </View> ); } }
render() { return ( <View style="styles.container"> <FlatList data={this.state.data} renderItem={this._renderItem} onRefresh={this.reloadData} refreshing={this.state.isRefresh} ListFooterComponent={this._footerView} onEndReached={this.loadMoreData} onEndReachedThreshold={1} ItemSeparatorComponent={this._seperator} > </FlatList> </View> ); } } |