ReactNaive之ScrollView和ListView
ReactNaive相關文章
1. React Native 中文網
2. GitHub相關代碼地址
3. ReactNaive之CSS和Flex布局
4. ReactNative之基本組件
5. React Naive之ScrollView和ListView
6. React Native之導航組件NavigatorIOS和Navigator
7. ReactNative之TabBariOS和TabNavigator
注: 本文主要總結的是ReactNative的一些簡單語法, 大部分內容總結自袁大神的文章
ListView.png
一. ScrollView
- 記住ScrollView必須有一個確定的高度才能正常工作,因為它實際上所做的就是將一系列不確定高度的子組件裝進一個確定高度的容器(通過滾動操作)
- 要給一個ScrollView確定一個高度的話,要么直接給它設置高度(不建議),要么確定所有的父容器都有確定的高度
1. ScrollView常用的屬性
horizontal bool
//當此屬性為true的時候,所有的子視圖會在水平方向上排成一行,而不是默認的在垂直方向上排成一列。默認值為false。
showsHorizontalScrollIndicator bool
//當此屬性為true的時候,顯示一個水平方向的滾動條。
showsVerticalScrollIndicator bool
//當此屬性為true的時候,顯示一個垂直方向的滾動條。
alwaysBounceHorizontal bool
//當此屬性為true時,水平方向即使內容比滾動視圖本身還要小,也可以彈性地拉動一截。當horizontal={true}時默認值為true,否則為false。
refreshControl element
//指定RefreshControl組件,用于為ScrollView提供下拉刷新功能
(ios) alwaysBounceVertical bool
//當此屬性為true時,垂直方向即使內容比滾動視圖本身還要小,也可以彈性地拉動一截。
//當horizontal={true}時默認值為false,否則為true。
(ios) automaticallyAdjustContentInsets bool
//當滾動視圖放在一個導航條或者工具條后面的時候,iOS系統是否要自動調整內容的范圍。默認值為true。(譯注:如果你的ScrollView或ListView的頭部出現莫名其妙的空白,嘗試將此屬性置為false)
(ios) bounces bool
//當值為true時,如果內容范圍比滾動視圖本身大,在到達內容末尾的時候,可以彈性地拉動一截。如果為false,尾部的所有彈性都會被禁用,即使alwaysBounce*屬性為true。默認值為true。
(ios) bouncesZoom bool
//當值為true時,使用手勢縮放內容可以超過min/max的限制,然后在手指抬起之后彈回min/max的縮放比例。否則的話,縮放不能超過限制。
(ios) contentInset {top: number, left: number, bottom: number, right: number}
//內容范圍相對滾動視圖邊緣的坐標。默認為{0, 0, 0, 0}
(ios) contentOffset PointPropType
//用來手動設置初始的滾動坐標。默認值為{x: 0, y: 0}
pagingEnabled bool
//當值為true時,滾動條會停在滾動視圖的尺寸的整數倍位置。這個可以用在水平分頁上。默認值為false。
scrollEnabled bool
//當值為false的時候,內容不能滾動,默認值為true。
(ios) scrollEventThrottle number
//這個屬性控制在滾動過程中,scroll事件被調用的頻率(單位是每秒事件數量)。更大的數值能夠更及時的跟蹤滾動位置,不過可能會帶來性能問題,因為更多的信息會通過bridge傳遞。默認值為0,意味著每次視圖被滾動,scroll事件只會被調用一次。
(ios)scrollIndicatorInsets {top: number, left: number, bottom: number, right: number}
//決定滾動條距離視圖邊緣的坐標。這個值應該和contentInset一樣。默認值為{0, 0, 0, 0}。
(ios) scrollsToTop bool
//當此值為true時,點擊狀態欄的時候視圖會滾動到頂部。默認值為true。
stickyHeaderIndices [number]
//一個子視圖下標的數組,用于決定哪些成員會在滾動之后固定在屏幕頂端。
//舉個例子,傳遞stickyHeaderIndices={[0]}會讓第一個成員固定在滾動視圖頂端。
//這個屬性不能和horizontal={true}一起使用。
(ios) maximumZoomScale number
//允許的最大縮放比例。默認值為1.0。
(ios) minimumZoomScale number
//允許的最小縮放比例。默認值為1.0。
2. ScrollView常用的方法
- 開發中,常需要在滾動的時候做事情,那怎么監聽ScrollView滾動
// 監聽滾動開始
onMomentumScrollBegin={this._onMomentumScrollBegin.bind(this)}
// 監聽滾動結束
onMomentumScrollEnd={this._onMomentumScrollEnd.bind(this)}
// 監聽開始拖拽
onScrollBeginDrag={this._onScrollBeginDrag.bind(this)}
// 監聽結束拖拽
onScrollEndDrag={this._onScrollEndDrag.bind(this)}
// 監聽滾動動畫完成
onScrollAnimationEnd={this._onScrollAnimationEnd.bind(this)}
onMomentumScrollStart?: function
//滾動動畫開始時調用此函數。
onMomentumScrollEnd?: function
//滾動動畫結束時調用此函數。
// 監聽滾動的時候
onScroll={this._onScroll.bind(this)}
// 設置滾動頻率,一滾動就監聽,需要和onScroll配套使用
scrollEventThrottle={1}
scrollTo(y: number | { x?: number, y?: number, animated?: boolean }, x: number, animated: boolean)
//滾動到指定的x, y偏移處。第三個參數為是否啟用平滑滾動動畫。
//使用示例:
scrollTo({x: 0, y: 0, animated: true})
scrollToEnd(options?)
//滾動到視圖底部(水平方向的視圖則滾動到最右邊)。
//加上動畫參數 scrollToEnd({animated: true})則啟用平滑滾動動畫,或是調用 scrollToEnd({animated: false})來立即跳轉。如果不使用參數,則animated選項默認啟用。
3. 獲取原生事件
- 滾動的時候,會傳入一個合成事件作為監聽滾動方法的參數,每個方法都會有這個合成事件
- 通過合成事件能獲取原生事件nativeEvent,原生事件nativeEvent會有我們想要的信息.
- 什么是合成事件:在RN中,事件的處理由其內部自己實現的事件系統完成,觸發的事件都叫做 合成事件(SyntheticEvent)
// 滾動完成的時候調用
_onMomentumScrollEnd(e){
// 獲取原生事件
var nativeEvent = e.nativeEvent
//獲取當前偏移量
var contentX = nativeEvent.contentOffset.x
//當前頁
var page = contentX / kScreenWidth
this.setState({
currentPage:page
})
}
二. ListView
- 官方文檔提示: 在0.46版本開始此組件已過期, 并推薦使用
FlatList
或SectionList
替代, 但是在0.51版本依然可以使用 -
ListView
: 一個核心組件,用于高效地顯示一個可以垂直滾動的變化的數據列表 - ListView內部是通過
ListViewDataSource
這個對象,顯示數據,因此使用ListView必須先創建ListViewDataSource
對象。 -
ListViewDataSource
構造方法(創建對象):可選擇性傳入4個參數,描述怎么提取數據,怎么刷新cell - 這些參數:都是函數,當產生對應的事件的時候,會自動執行這些函數.
1. ListView常用的屬性和方法
- ListView可以使用所有ScrollView的屬性。
initialListSize number
//指定在組件剛掛載的時候渲染多少行數據。用這個屬性來確保首屏顯示合適數量的數據,而不是花費太多幀逐步顯示出來
dataSource ListViewDataSource
//ListView.DataSource實例(列表依賴的數據源)
-
ListViewDataSource
構造函數可以接受下列四種參數(都是可選):
getRowData(dataBlob, sectionID, rowID);
//怎么獲取行數據
getSectionHeaderData(dataBlob, sectionID);
//怎么獲取每一組頭部數據
rowHasChanged(prevRowData, nextRowData);
//決定什么情況行數據才發生改變,當行數據發生改變,就會繪制下一行cell
sectionHeaderHasChanged(prevSectionData, nextSectionData);
//決定什么情況頭部數據才發生改變,當行數據發生改變,就會繪制下一行cell
-
ListViewDataSource
為ListView
組件提供高性能的數據處理和訪問。我們需要調用clone方法從原始輸入數據中抽取數據來創建ListViewDataSource
對象。 - 要更新
datasource
中的數據,請(每次都重新)調用cloneWithRows
方法(如果用到了section,則對應cloneWithRowsAndSections
方法)clone方法會自動提取新數據并進行逐行對比(使用rowHasChanged
方法中的策略),這樣ListView
就知道哪些行需要重新渲染了 - 注意:初始化
ListViewDataSource
的時候,如果不需要修改提取數據的方式,只需要實現rowHasChanged
,告訴什么時候刷新下一行數據. - 注意:默認
ListViewDataSource
有提取數據方式,可以使用默認的提取方式.
2. ListView使用步驟
- 1). 創建數據源
//1. 創建數據源對象
var datas = new ListView.DataSource({
//設置數據改變的時候刷新下一行數據
rowHasChanged: (r1, r2)=>{r1 != r2},
})
//2. 請求數據'
var foodArr = require('./Resource/food.json')
//3. 設置數據
datas = datas.cloneWithRows(foodArr)
//5. 保存數據源
this.state = {
dataArr: datas
}
- 2). ListView實現
<ListView style={{backgroundColor:'white', marginTop:20}}
//設置數據源
dataSource={this.state.dataArr}
//渲染哪一行(設置cell樣式)
renderRow={this._renderRow.bind(this)}
//設置頭部樣式
renderHeader={this._renderHeader.bind(this)}
//設置section的頭部樣式
renderSectionHeader={this._renderSectionHeader.bind(this)}
//設置尾部樣式
renderFooter={this._renderFooter.bind(this)}
//設置分割線樣式
renderSeparator={this._renderSeparator.bind(this)}
/>
- 3). 相關屬性方法介紹
- renderRow: 設置每行cell樣式
// 實現數據源方法,設置每行cell樣式
/*這個方法會自動傳入四個參數(rowData,sectionID,rowID,highlightRow)
rowData:當前行數據
sectionID:當前行所在組ID
rowID:哪一行的角標
highlightRow:高亮函數
*/
_renderRow(rowData, sectionID, rowID, highlightRow) {
return (
<View>
<Text>{rowData}</Text>
</View>
);
}
- ListView頭部和尾部視圖
//頭部視圖
_renderHeader() {
return (
<View>
<Text>頭部視圖</Text>
</View>
)
}
//尾部視圖
_renderFooter() {
return (
<View>
<Text>尾部視圖</Text>
</View>
)
}
- renderSectionHeader: 設置每一個section的頭部樣式
//sectionData: 每一組的頭部數據
//sectionID: 組ID
_renderSectionHeader(sectionData, sectionID){
}
- ListView分割線
// 哪一組,哪一行,相鄰行是否高亮
_renderSeparator(sectionID, rowID, adjacentRowHighlighted) {
console.log(sectionID,rowID,adjacentRowHighlighted);
return (
<View style={{height:1,backgroundColor:'black'}}></View>
)
}