ListView加載圖片錯位

什麼導致圖片錯亂?怎麼解決?

錯亂的原因是異步加載以及Convertview對象複用造成的。

首先給ImageView設置一個Tag,這個Tag中設置的是圖片的Url,   

  然後在加載的時候取得這個Url要和加載的那個Position中Url對比,   

如果不同就加載,相同的話就複用以前的,不加載。


原理:

一個屏幕顯示了幾條,會在下面默認繪製一條默認的,例顯示了4條

當第一條移出屏幕的時候會將這一條目給6條使用,

每當有新的元素進入界面時就會回調getView()方法,而在getView()方法中會開啓異步請求從網絡上獲取圖片(注意:網絡操作都是比較耗時的),也就是說當我們快速滑動ListView的時候就很有可能出現這樣一種情況,某一個位置上的元素進入屏幕後開始從網絡上請求圖片,但是還沒等圖片下載完成,它就又被移出了屏幕。這種情況下會產生什麼樣的現象呢?根據ListView的工作原理,被移出的條目將很快會被新進入屏幕的條目所複用,而如果在這個時候剛好前面發起的圖片請求有了響應,就會將已經移出的條目上要顯示的圖片加載到當前位置上,因爲雖然它們位置不同,但都是共用的同一個ImageView實例,這樣的話就出現了圖片亂序的情況。

解決方案一  使用findViewWithTag

其實就是在getview方法裏面,給imageview用setTag設置一個tag

這個setTag()方法,可以把當前位置圖片的URL地址作爲參數傳了進去,這個是爲後續的findViewWithTag()方法做準備。在onPostExecute()方法當中通過ListView的findVIewWithTag()方法來去獲取ImageView控件的實例。獲取到控件實例後判斷下是否爲空,如果不爲空就讓圖片顯示到控件上。

因爲ListView中的ImageView控件都是重用的,移出屏幕的控件很快會被進入屏幕的圖片重新利用起來,那麼getView()方法就會再次得到執行,而在getView()方法中會爲這個ImageView控件設置新的Tag,這樣老的Tag就會被覆蓋掉,於是這時再調用findVIewWithTag()方法並傳入老的Tag,就只能得到null了,而我們判斷只有ImageView不等於null的時候纔會設置圖片,這樣圖片亂序的問題也就不存在了。

解決方案二  使用NetworkImageView

NetworkImageView是Volley當中提供的控件

將xml佈局中將Imageview換成NetworkImageView,

setDeafaultImageResld():佔位圖

setErrorImageResld():加載圖片出錯的圖

setImageUrl():顯示所要的圖片

可以設置默認的佔位圖,設置加載圖片出錯的圖片,可以用第三個方法加載要顯示的正確的圖片

ImageContainer對象中獲取封裝的圖片請求地址,並拿來和當前的請求地址做對比,如果相同,就說明這是一條重複的請求,就直接return掉;如果不同,就調用cancelRequest()方法將請求取消,然後將這張圖片設置爲默認的,然後再發送一遍請求


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章