本文由作者鄒啟文授權(quán)網(wǎng)易云社區(qū)發(fā)布。
在郵箱大師選擇duilib作為UI開發(fā)庫后,我們面臨這樣一個(gè)問題。隨著時(shí)間的積累,用戶數(shù)據(jù)會(huì)越來越多,如何保證我們的軟件在展示這些數(shù)據(jù)時(shí)依然保持非常好的體驗(yàn)?
??????原生態(tài)duilib列表的實(shí)現(xiàn)是,數(shù)據(jù)與控件(列表的每一項(xiàng))一一對(duì)應(yīng),即有多少數(shù)據(jù),便有多少控件。通過粗略測(cè)試,我們發(fā)現(xiàn),當(dāng)數(shù)據(jù)量達(dá)到10000封郵件時(shí),僅僅是構(gòu)造這10000個(gè)控件就需要花費(fèi)16s,也就是說在這16s內(nèi),用戶無法操作軟件,這是我們無法接受的。所以,我們決定改進(jìn)duilib列表,通過虛擬化的方式解決這個(gè)問題。
??????虛擬化,就是,對(duì)于10000封郵件,我們并不需要構(gòu)造10000個(gè)控件,因?yàn)檎嬲梢宰層脩艨匆姷牟怀^20(根據(jù)屏幕高度和控件高度計(jì)算)個(gè)控件,那么,我們可以通過反復(fù)利用這20個(gè)控件來達(dá)到展示10000封郵件的目的。
??????那么,具體如何實(shí)現(xiàn)呢?很簡單,在鼠標(biāo)上下滾動(dòng)的時(shí)候,我們對(duì)這20個(gè)控件重新布局(更改其位置)和更新其內(nèi)容。
??????但是,產(chǎn)品和視覺提出了一個(gè)需求,給列表滾動(dòng)加上動(dòng)畫效果,即用戶滾動(dòng)列表松開鼠標(biāo)后,列表內(nèi)容仍要向上或向下以一定的速度前進(jìn),之后才停下來。那么,上面的方案便行不通,因?yàn)?0個(gè)控件在滾動(dòng)時(shí)不斷重新布局和更新內(nèi)容比較耗時(shí),會(huì)導(dǎo)致列表出現(xiàn)卡頓式的前進(jìn),用戶體驗(yàn)太差。如何解決這個(gè)問題呢?
??????我們的解決辦法是采用100個(gè)控件。這樣,在滾動(dòng)時(shí)判斷是否需要重新布局,如果不需要,則直接刷新繪制新的郵件內(nèi)容,如果到了臨界條件,那么再重新布局然后繪制新的郵件內(nèi)容。具體做法如下:
臨界條件的判斷:
假設(shè)滾動(dòng)條的位置為yScrollPos,列表的區(qū)域?yàn)閞cList,第一個(gè)列表項(xiàng)的位置為rcFirst,最后一個(gè)列表項(xiàng)的位置為rcLast。
當(dāng)yScrollPos > (rcLast.bottom-rcList.top)-rcList.Height時(shí),為向下滾動(dòng)的臨界條件;
當(dāng)yScrollPos < rcFirst.top-rcList.top時(shí),為向上滾動(dòng)的臨界條件。
1,向下滾動(dòng)到臨界條件
特別注意:存在靠近最底部時(shí)重新布局的情況,100個(gè)列表項(xiàng)的后面不可見的一部分項(xiàng)可以置為無效。
2,向上滾動(dòng)到臨界條件
特別注意:存在靠近頂部時(shí)重新布局的情況,此時(shí),與上面圖不同的是,大部分項(xiàng)會(huì)布局在下面,少部分在上面,但是沒有關(guān)系,因?yàn)榇撕笙蛏蠞L動(dòng),不會(huì)再觸發(fā)重新布局。
目前郵箱大師中,虛擬列表應(yīng)用在郵件列表、通訊錄列表、寫信聯(lián)系人列表等,極大提高了軟件運(yùn)行性能和體驗(yàn),而且運(yùn)行穩(wěn)定。
免費(fèi)領(lǐng)取驗(yàn)證碼、內(nèi)容安全、短信發(fā)送、直播點(diǎn)播體驗(yàn)包及云服務(wù)器等套餐
更多網(wǎng)易技術(shù)、產(chǎn)品、運(yùn)營經(jīng)驗(yàn)分享請(qǐng)?jiān)L問網(wǎng)易云社區(qū)。
相關(guān)文章:
【推薦】?實(shí)戰(zhàn)案例:如何快速打造1000萬+播放量的抖音網(wǎng)紅?