商城頁面-MerchandiseGrid
使用
numColumns
為 2 欄
<FlatList
keyExtractor={this.keyExtractor}
numColumns={2}
data={this.state.data}
renderItem={this.renderItem}
/>
再來用flex 0.5
的方式把list item 做平分
const styles = StyleSheet.create({
listItem: {
margin: 10,
flex: 0.5
},
})
..
renderItem = ()=> {
return (
<TouchableOpacity onPress={this.goMerchandiseDetail} style={styles.listItem}>
{...}
</TouchableOpacity>
)
}
壓上折扣UI

Image 上 疊加Text
對Text 設定背景色與字體顏色
自製TabBar
利用ScrollView 做水平捲移動,並關掉ScrollIndictator...
在裡面包裹
TouhableHighlight
做選中處理 ,可以是更改背景色或是加上框線根據儲存的state 來得知有無被按下,並設定框線
使用`contentContanierStyle 教item 排列設為flexDirection:'row'
const styles = StyleSheet.create({
container: {
flexDirection: 'row'
},
})
export default class TabBar {
static propTypes = {
tabs: PropTypes.array.isRequired,
onTabPress: PropTypes.func.isRequired
}
render(){
return (
<ScrollView
contentContainerStyle={styles.container}
horizontal
showsHorizontalScrollIndicator={false}
>
<TouchableHighlight
underlayColor="transparent"
activeOpacity={1}
onPress={() => {
this.onTabPress(tab);
}}
style={ [ styles.tab, selected[tab.type] && { borderColor: 'white' } ] }
key={tab.type}
>
</TouchableHighlight>
</ScrollView>
)
}
}
Styles v.s ContentContainerStyle
ScrollView 與 FlatList 都利用 contentContainer. height > style.height 來判斷是否需要scrollBar
所以不能把
contentContainerStyle
設為{flex: 1}
,否則失去scroll 效果e.g 畫面高長的width 為 640,但contentContainer 因item 超過範圍而變成 1024,這時把contentContainerStyle 設為 {flex: 1},則contentContainer 的width 變為 640 ,導致無法進行scroll
偵測程式是在背景(background)還是前景(foreground)
在商品總覽中,利用此項機制,當使用者切回App時,重新刷新一次list,讓使用者看到最新的商品。
在componentDidMount 進行註冊
由於該listener 是從Native 曾回呼的,所以當該listener 發生錯誤後,在開發時會導致App Crash 而非 JS 層 的unhandled error
import {
StyleSheet,
View,
Text,
FlatList,
Image,
TouchableOpacity,
TextInput,
AppState
} from 'react-native';
export default class Example extends Component {
state = {
appState: AppState.currentState
};
refresh = ()=>{
//刷新list
}
handleAppStateChange = (nextAppState) => {
if (nextAppState === 'active') {
this.refresh();
}
};
componentDidMount() {
AppState.addEventListener('change', this.handleAppStateChange);
}
componentWillUnmount() {
AppState.removeEventListener('change', this.handleAppStateChange);
}
}
加入PullToRefresh 的機制
新增
refreshing
與onRefresh
屬性在即將開始刷新之前,變更
this.state.refreshing
再刷新之後,再變更
this.state.refreshing
為false因為是測試資料,利用shuffle的方式改變測試資料的順序,模擬資料不同的情況
export default class Example {
shuffle = arr => arr.sort(() => Math.random() - 0.5);
onRefresh = () => {
this.setState({
refreshing: true
});
setTimeout(() => {
this.setState({
refreshing: false,
data: this.shuffle(this.state.data)
});
}, 1000);
};
render(){
return (
<FlatList
refreshing={this.state.refreshing}
onRefresh={this.onRefresh}
{...}
/>
)
}
}
使用onEndReached 實現Pagination
API (pageNum: 1, numberOfItems: 20)
nextPageToken, maxResult
<FlatList onEndReached={() => { const nextPageToken = 'ABC' // {pageNum: this.state.pageNum++, numberOfItems: 20} this.refresh(nextPageToken); }} />
使用
onEndReachThreshold
(0 ~ 1, 0.5 )
NetInfo 偵測網路狀態 與 ListEmptyView
ListEmptyView的三種狀態
Wifi/3G 未連上
連上了,但獲取不到資料
本來就是空的
設置NetInfo 偵測網路狀態並在
ListEmptyComponent
加入自製EmptyView
import {
StyleSheet,
View,
Text,
FlatList,
NetInfo
} from 'react-native';
const CONNECTION_ERROR = {
offline: '網路斷線了',
unknown: '未知的錯誤'
};
export default class Example {
componentDidMount() {
NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectivity);
}
componentWillUnmount() {
NetInfo.isConnected.addEventListener('connectionChange', this.handleConnectivity);
}
emptyView = () => {
const { error } = this.state;
return (
<View style={[styles.container, styles.center]}>
<Text>{CONNECTION_ERROR[error]}</Text>
</View>
);
};
handleConnectivity = (isConnected) => {
if (!isConnected) {
this.setState({
data: [],
error: 'offline'
});
} else {
// refetch your data
this.refresh();
}
this.setState({
isConnected
});
};
render(){
return (
<FlatList
ListEmptyComponent={this.emptyView}
refreshing={this.state.refreshing}
onRefresh={this.refresh}
contentContainerStyle={styles.merchandiseGrid}
keyExtractor={this.keyExtractor}
numColumns={2}
data={this.state.data}
renderItem={this.renderItem}
/>
)
}
}
但是emptyView 的文字居然沒有垂直置中...
Center EmptyView's PR which intend to release react-native 0.56
自己來
當data 是空的時候,隱藏FlatList,然後切換至EmptyView
Last updated
Was this helpful?