FlatList
React Native 提供了幾個適用於展示長列表數據的組件,一般而言我們會選用FlatList或SectionList。
其實FlatList就是android中的ListView。
FlatList組件用於顯示一個垂直的滾動列表,其中的元素之間結構近似而僅數據不同。
FlatList更適於長列表數據,且元素個數可以增刪。和ScrollView不同的是,FlatList並不立即渲染所有元素,而是優先渲染屏幕上可見的元素。
FlatList組件必須的兩個屬性是data和renderItem。data是列表的數據源,而renderItem則從數據源中逐個解析數據,然後返回一個設定好格式的組件來渲染。
下面的例子創建了一個簡單的FlatList,並預設了一些模擬數據。首先是初始化FlatList所需的data,其中的每一項(行)數據之後都在renderItem中被渲染成了Text組件,最後構成整個FlatList。
官方案例:
import React, { Component } from 'react';
import { FlatList, StyleSheet, Text, View } from 'react-native';
export default class FlatListBasics extends Component {
render() {
return (
<View style={styles.container}>
<FlatList
data={[
{key: 'Devin'},
{key: 'Jackson'},
{key: 'James'},
{key: 'Joel'},
{key: 'John'},
{key: 'Jillian'},
{key: 'Jimmy'},
{key: 'Julie'},
]}
renderItem={({item}) => <Text style={styles.item}>{item.key}</Text>}
/>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
paddingTop: 22
},
item: {
padding: 10,
fontSize: 18,
height: 44,
},
})
FlatList案例
import React, {Component} from 'react';
import {StyleSheet, FlatList, Text, View} from "react-native";
const CITY_NAMES = ["北京", "上海", "廣州", "深圳", "成都", "武漢", "南京"];
type Props = {};
export default class App extends Component<Props> {
render() {
return (
<View style={styles.container}>
<FlatList
data={CITY_NAMES}
renderItem={(data) => this.renderItemView(data)}
/>
</View>
);
}
renderItemView(data) {
return <View style={styles.item}>
<Text style={styles.text}>{data.item}</Text>
</View>
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
backgroundColor: "#169",
height: 200,
margin: 15,
justifyContent: "center",
alignItems: "center"
},
text: {
color: "white",
fontSize: 20,
}
});
實現下拉刷新
import React, {Component} from 'react';
import {StyleSheet, FlatList, Text, View} from "react-native";
const CITY_NAMES = ["北京", "上海", "廣州", "深圳", "成都", "武漢", "南京"];
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
isLoading: false, //默認沒有下拉刷新
dataArray: CITY_NAMES //默認數據
}
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.dataArray}
renderItem={(data) => this.renderItemView(data)}
//下拉刷新
refreshing={this.state.isLoading}
onRefresh={() => {
this.loadData(); //下拉刷新加載數據
}}
/>
</View>
);
}
renderItemView(data) {
return <View style={styles.item}>
<Text style={styles.text}>{data.item}</Text>
</View>
}
loadData() {
this.setState({
isLoading: true
})
//模擬網絡請求
setTimeout(() => {
//把數據反轉
let newArray = [];
for (let i = this.state.dataArray.length - 1; i >= 0; i--) {
newArray.push(this.state.dataArray[i]);
}
this.setState({
isLoading: false,
dataArray: newArray
})
}, 3000);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
backgroundColor: "#169",
height: 200,
margin: 15,
justifyContent: "center",
alignItems: "center"
},
text: {
color: "white",
fontSize: 20,
}
});
設置下拉刷新樣式
<FlatList
data={this.state.dataArray}
renderItem={(data) => this.renderItemView(data)}
//設置下拉刷新樣式
refreshControl={
<RefreshControl
title={"Loading"} //android中設置無效
colors={["red"]} //android
tintColor={"red"} //ios
titleColor={"red"}
refreshing={this.state.isLoading}
onRefresh={() => {
this.loadData(); //下拉刷新加載數據
}}
/>
}
/>
實現上拉加載
//上拉加載
ListFooterComponent={() => this.renderLoadMoreView()}
onEndReached={() => this.loadMoreData()}
renderLoadMoreView() {
return <View style={styles.loadMore}>
<ActivityIndicator
style={styles.indicator}
size={"large"}
color={"red"}
animating={true}
/>
<Text>正在加載更多</Text>
</View>
}
loadMoreData() {
//模擬網絡請求
setTimeout(() => {
let newArray = [];
for (let i = this.state.dataArray.length - 1; i >= 0; i--) {
newArray = this.state.dataArray.concat(CITY_NAMES)
}
this.setState({
dataArray: newArray
})
}, 3000);
}
完整代碼
import React, {Component} from 'react';
import {StyleSheet, FlatList, Text, View, RefreshControl, ActivityIndicator} from "react-native";
const CITY_NAMES = ["北京", "上海", "廣州", "深圳", "成都", "武漢", "南京"];
type Props = {};
export default class App extends Component<Props> {
constructor(props) {
super(props);
this.state = {
isLoading: false, //默認沒有下拉刷新
dataArray: CITY_NAMES //默認數據
}
}
render() {
return (
<View style={styles.container}>
<FlatList
data={this.state.dataArray}
renderItem={(data) => this.renderItemView(data)}
//設置下拉刷新樣式
refreshControl={
<RefreshControl
title={"Loading"} //android中設置無效
colors={["red"]} //android
tintColor={"red"} //ios
titleColor={"red"}
refreshing={this.state.isLoading}
onRefresh={() => {
this.loadData(); //下拉刷新加載數據
}}
/>
}
//設置上拉加載
ListFooterComponent={() => this.renderLoadMoreView()}
onEndReached={() => this.loadMoreData()}
/>
</View>
);
}
//條目佈局
renderItemView(data) {
return <View style={styles.item}>
<Text style={styles.text}>{data.item}</Text>
</View>
}
//下拉刷新數據
loadData() {
this.setState({
isLoading: true
})
//模擬網絡請求
setTimeout(() => {
//把數據反轉
let newArray = [];
for (let i = this.state.dataArray.length - 1; i >= 0; i--) {
newArray.push(this.state.dataArray[i]);
}
this.setState({
isLoading: false,
dataArray: newArray
})
}, 3000);
}
//上拉加載佈局
renderLoadMoreView() {
return <View style={styles.loadMore}>
<ActivityIndicator
style={styles.indicator}
size={"large"}
color={"red"}
animating={true}
/>
<Text>正在加載更多</Text>
</View>
}
//上拉加載更多數據
loadMoreData() {
//模擬網絡請求
setTimeout(() => {
let newArray = [];
for (let i = this.state.dataArray.length - 1; i >= 0; i--) {
newArray = this.state.dataArray.concat(CITY_NAMES)
}
this.setState({
dataArray: newArray
})
}, 3000);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
item: {
backgroundColor: "#169",
height: 200,
margin: 15,
justifyContent: "center",
alignItems: "center"
},
text: {
color: "red",
fontSize: 20,
},
loadMore: {
alignItems: "center"
},
indicator: {
color: "red",
margin: 10
}
});