Demo展示
之前兩篇文章ListView的學(xué)習(xí)都是展示了每一row的數(shù)據(jù)蜈亩,而上面的效果圖中不僅展示了row數(shù)據(jù)懦窘,而且還帶有一個(gè)section header,當(dāng)滑動(dòng)時(shí),這個(gè)section header會(huì)固定在頭部稚配,也就是吸頂效果畅涂。但是遺憾的是,在Android平臺(tái)上不支持吸頂效果,如下圖:
Demo知識(shí)點(diǎn)
那如何來(lái)實(shí)現(xiàn)它了道川?我們都知道午衰,在只簡(jiǎn)單地渲染每一行數(shù)據(jù)時(shí)立宜,我們獲取數(shù)據(jù)源時(shí)用ListView對(duì)象的cloneWithRows方法來(lái)獲取的,而想要實(shí)現(xiàn)這種吸頂效果的話臊岸,需要使用 cloneWithRowsAndSections 方法橙数。這個(gè)方法需要傳入三個(gè)參數(shù):
dataBlob object類型
sectionIDs array婁型
rowIDs array類型
- dataBlob
它是一種數(shù)據(jù)結(jié)構(gòu),包含ListView所需的所有數(shù)據(jù)(section header 和 rows)帅戒,如下圖:
<font color=#ff0000 size=5 face="黑體">dataBlob 的 key 值包含 sectionID + rowId</font>,我們可以通過(guò)getSectionData 和 getRowData 來(lái)渲染每一行數(shù)據(jù)灯帮。
- sectionIDs
sectionIDs 用于標(biāo)識(shí)每組section,如下圖:
- rowIDs
rowIDs 用于描述每個(gè) section 里的每行數(shù)據(jù)的位置及是否需要渲染逻住。在ListView渲染時(shí)钟哥,會(huì)先遍歷 rowIDs 獲取到對(duì)應(yīng)的 dataBlob 數(shù)據(jù)。
Demo實(shí)現(xiàn)
-
數(shù)據(jù)內(nèi)容
{ "data": [ { "cars": [ { "icon": "m_180_100", "name": "AC Schnitzer" }, { "icon": "m_92_100", "name": "阿爾法·羅密歐" }, { "icon": "m_9_100", "name": "奧迪" }, { "icon": "m_97_100", "name": "阿斯頓·馬丁" } ], "title": "A" }, ... ] }
這里的'cars'和'title'屬于data數(shù)據(jù)的一組瞎访,也就是我們上面講的一組section數(shù)據(jù)腻贰,而它的sectionId就是0,因?yàn)槭菙?shù)組的第一個(gè)元素扒秸。然后title屬于sectionHeader银受,而cars就是我們的row數(shù)據(jù),而它的rowsId分別為:0~3
-
主要實(shí)現(xiàn)
-
初始化ListView的dataSource對(duì)象鸦采,并且設(shè)置獲取sectionHeader和sectionRow數(shù)據(jù)
constructor(props) { super(props); var getSectionData = (dataBlob, sectionID) => { return dataBlob[sectionID]; }; var getRowData = (dataBlob, sectionID, rowID) => { return dataBlob[sectionID + ':' + rowID]; }; this.state = { dataSource: new ListView.DataSource({ getSectionData: getSectionData, // 獲取組中數(shù)據(jù) getRowData: getRowData, // 獲取行中的數(shù)據(jù) rowHasChanged: (r1, r2) => r1 !== r2, sectionHeaderHasChanged: (s1, s2) => s1 !== s2 }) }; }
-
獲取json數(shù)據(jù),并將其放放dataBlob對(duì)象中
var jsonData = this.props.data; var dataBlob = {}, sectionIDs = [], rowIDs = [], cars = []; for (var i in jsonData) { //step 1咕幻、把組數(shù)據(jù)放入sectionIDs數(shù)組中 sectionIDs.push(i); //step 2渔伯、把組中內(nèi)容放dataBlob對(duì)象中 dataBlob[i] = jsonData[i].title; //step 3、取出該組中所有的車 cars = jsonData[i].cars; //step 4記錄每一行中的數(shù)據(jù) rowIDs[i] = []; //step 5肄程、獲取行中每一組數(shù)據(jù) for (var j in cars) { //把行號(hào)放入rowIDs中 rowIDs[i].push(j); //把每一行中的內(nèi)容放dataBlob對(duì)象中 dataBlob[i + ':' + j] = cars[j]; } }
-
刷新狀態(tài)锣吼,將數(shù)據(jù)傳入到listView中
this.setState({ dataSource: this.state.dataSource.cloneWithRowsAndSections(dataBlob, sectionIDs, rowIDs) });
-
渲染ListView,設(shè)置相關(guān)屬性
<ListView dataSource={this.state.dataSource} renderRow={this.renderRow.bind(this)} renderSectionHeader={this.renderSectionHeader.bind(this)} />
-
好了蓝厌。ListView吸頂效果的學(xué)習(xí)就完成了玄叠。完整代碼
參考資料
http://moduscreate.com/react-native-listview-with-section-headers/