Android基礎(chǔ)10-ListView優(yōu)化

ListView優(yōu)化技巧

一、上節(jié)回顧:

(一)、充分理解convertView的作用:

1、手機(jī)程序運(yùn)行后的效果圖:

2、剛運(yùn)行后的LogCat記錄:

3、屏幕滑動(dòng)后的效果截圖:

4、屏幕滑動(dòng)后的LogCat記錄:

【說(shuō)明:】手機(jī)屏幕中一次展示10條數(shù)據(jù),所以第一次加載時(shí),新建了10個(gè)ViewHolder對(duì)象。這10個(gè)對(duì)象的id從截圖中可以看到:@411e8a18、@413ab880等等。

當(dāng)屏幕滑動(dòng),有些item滑出屏幕,又有新的item從底端進(jìn)入屏幕。可以看到新item進(jìn)入屏幕時(shí)只有一個(gè)是新建ViewHolder,其他的都是重復(fù)使用convertView。

二、ListView優(yōu)化中的細(xì)節(jié)問(wèn)題:

1、android:layout_height屬性:

????? ? 必須將ListView的布局高度屬性設(shè)置為非“wrap_content”(可以是“match_parent / ?fill_parent ?/ ?400dp等絕對(duì)數(shù)值”),如果ListView的布局高度為“wrap_content”,那么getView()就會(huì)重復(fù)調(diào)用。一般來(lái)說(shuō),一個(gè)item會(huì)被調(diào)用四次左右。

2、ViewHolder:

????? ? 利用ViewHolder內(nèi)部類,將item布局文件中需要展示的控件定義為屬性(其實(shí)ViewHolder就是一個(gè)自定義的模型類)。這樣就把item中散在的多個(gè)控件合成一個(gè)整體,這樣可以有效地避免圖片錯(cuò)位。

3、convertView:

? ? ? ? ListView的加載是一個(gè)item一個(gè)item的加載,這樣就會(huì)每次都inflate一個(gè)item布局,然后findViewById一遍該布局上的所有控件。當(dāng)數(shù)據(jù)量大的時(shí)候,是不可想象的。而利用Recycle回收利用就可以解決問(wèn)題。所以要善于重復(fù)利用convertView,這樣可以減少填充布局的過(guò)程,減少ViewHolder對(duì)象實(shí)例化的次數(shù)。減少內(nèi)存開(kāi)銷,提高性能。

4、convertView的setTag():

????? ? 利用setTag()方法將ViewHolder對(duì)象作為標(biāo)簽附加到convertView上,當(dāng)convertView被重復(fù)利用的時(shí)候,因?yàn)樯厦嬗蠽iewHolder對(duì)象,所以convertView就具有了ViewHolder中的幾個(gè)屬性,這樣就節(jié)省了findViewById()這個(gè)過(guò)程。如果一個(gè)item有三個(gè)控件,如果有100條item,那么在加載數(shù)據(jù)過(guò)程中,就就相當(dāng)于節(jié)省了幾百次findViewById(),節(jié)約了執(zhí)行findViewById()的時(shí)間,提升了加載速度,節(jié)省了性能的開(kāi)銷。

5、LayoutInflater對(duì)象的inflate()方法:

? ??inflate()方法一般接收兩個(gè)參數(shù),第一個(gè)參數(shù)就是要加載的布局id,第二個(gè)參數(shù)是指給該布局的外部再嵌套一層父布局,如果不需要就直接傳null。

? ??inflate()方法還有個(gè)接收三個(gè)參數(shù)的方法重載

1. 如果root為null,attachToRoot將失去作用,設(shè)置任何值都沒(méi)有意義。2. 如果root不為null,attachToRoot設(shè)為true,則會(huì)在加載的布局文件的最外層再嵌套一層root布局。3. 如果root不為null,attachToRoot設(shè)為false,則root參數(shù)失去作用。4. 在不設(shè)置attachToRoot參數(shù)的情況下,如果root不為null,attachToRoot參數(shù)默認(rèn)為true。

????? ? 所以在使用LayoutInflater填充布局的時(shí)候,要注意inflate()方法的參數(shù)。如果是兩個(gè)參數(shù),則第二個(gè)參數(shù)可以采用null;如果使用三個(gè)參數(shù)的方法,則要注意參數(shù)之間的搭配。

【備注:】

獲取填充器的三種方法:

LayoutInflater inflater =?getLayoutInflater();

LayoutInflater inflater = (LayoutInflater)?getSystemService(Context.LAYOUT_INFLATER_SERVICE);

LayoutInflater inflater = LayoutInflater.from(MainActivity.this);

6、監(jiān)聽(tīng)屏幕的滾動(dòng)狀態(tài)的變動(dòng)情況:

? ? ListView對(duì)象有OnScrollListener監(jiān)聽(tīng)器。其回調(diào)方法onScrollStateChanged(AbsListView view, int scrollState)的第二個(gè)參數(shù)就是屏幕滾動(dòng)狀態(tài)。

? scrollState = SCROLL_STATE_TOUCH_SCROLL(1):表示正在滾動(dòng)。當(dāng)屏幕滾動(dòng)且用戶使用的觸碰或手指還在屏幕上時(shí)為1

? scrollState =SCROLL_STATE_FLING(2) :表示手指做了拋的動(dòng)作(手指離開(kāi)屏幕前,用力滑了一下,屏幕產(chǎn)生慣性滑動(dòng))。

? scrollState =SCROLL_STATE_IDLE(0) :表示屏幕已停止。屏幕停止?jié)L動(dòng)時(shí)為0。

? ? 在以上三種屏幕滾動(dòng)狀態(tài)中,如果還處于SCROLL_STATE_FLING狀態(tài),則說(shuō)明屏幕還處于慣性滑動(dòng)狀態(tài),此時(shí)可以不進(jìn)行異步加載圖片。這樣可以節(jié)省不必要的性能開(kāi)銷。

7、item中如果包含button,則事件會(huì)發(fā)生沖突。如何解決控件之間的事件沖突,將在Android事件分發(fā)機(jī)制(touch event)中講解。


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容