首先來看看效果圖對比 ScrollView和SectionList
需求
頁面包含當前定位,熱門城市,全國的城市列表。其中全國城市列表頁帶字母分類,右側帶有字母索引
講道理,要完成這個需求,我能想到的是城市列表如何實現?ScrollView、FlatList、SectionList。
當然經過思考後,首先想到的是用SectionList來完成,所以第一版出來的效果是SectionList元件完成的頁面。但是,這時候遇到了個問題,因為全國城市的數量過多,在SectionList渲染完可視的頁面後,點選右側索引跳轉到對應的字母區域的滾動效果不太好,而且會有空白的渲染問題。
不過在使用支付寶APP的裡面定位功能時候,載入和跳轉索引都非常流暢,我就好奇是怎麼實現的了。肯定不是使用SectionList,Google後相關資料後嘗試了用ScrollView做了第二版,最後的結果如支付寶的元件版順暢。
ScrollView版的城市列表
首先看頁面佈局,全國城市列表的資料自己查詢一份,資料格式自己處理了一遍,大概是這個格式。之所以轉化成這樣是因為第一版用SectionList的資料來源必須是這種格式,包含key和data(必須是這個名字)
城市列表JSON資料圖片
頁面佈局的程式碼如圖
頁面佈局程式碼
詳細的參考程式碼去吧,接下來聊聊實現思路
開發思路
- 獲取字母表頭(索引陣列)
我們可以通過遍歷來獲取大寫字母
_gotLettersArray() {
let LettersArray = []
for (let i = 0; i < cityDatas.length; i++) {
let element = cityDatas[i];
LettersArray.push(element.title)
}
return LettersArray
}
複製程式碼
- 獲取每個字母區域的高度
首先定義一個空陣列用於存放每個字母區域的高度,其次初始化一個變數,其值與沒個城市列表的高度相同,最後遍歷得到沒個區域的高度並將其放進去,這樣便得到一個完整的儲存高度的陣列了
_gotTotalHeightArray() {
let totalArray = []
for (let i = 0; i < cityDatas.length; i++) {
let eachHeight = ROW_HEIGHT * (cityDatas[i].data.length + 1);
totalArray.push(eachHeight);
}
return totalArray
}
複製程式碼
- 點選右側字母自動滑動到相應位置
當我們點選右側字母時進入點選事件,通過scrollTo()使頁面跳轉到相應下標的高度上去。
scrollToList(item, index) {
let position = 0;
for (let i = 0; i < index; i++) {
position += totalHeight[i]
}
this.refs.ScrollView.scrollTo({y: position})
}
複製程式碼
最後
這就是用ScrollView完成的城市列表,相對來說簡單多了,而且體驗也更好,更多請參考程式碼