1. 程式人生 > >listView非同步載入圖片導致圖片錯位、閃爍、重複的問題的解決

listView非同步載入圖片導致圖片錯位、閃爍、重複的問題的解決

 androidListView是android中重要的控制元件,幾乎每一個專案都會用到。但是在使用中我們避免不

了會出現一些問題,包括一些滑動事件的處理,例如:ListView中巢狀scrollView,容易出現listView
展現資料不全的問題,還有就是listView中我們在載入圖片的時候出現圖片在載入中出現加載出來
的圖片出現閃爍,在滑動listView中我們我們都會複用listView的快取展示下一條的資料,其實我
們使用快取也是為了提高listView的效率,減少記憶體的耗費,下面我就說說我在使用listView的時
候出現的問題及解決方案吧,一是作為筆記來儲存,方便以後更深的理解和學習。二是讓在學習
的小夥伴們不在出現這種問題,因為對於初學者來說(比如我)也是一種理解吧.
listView出現這種原因重要的就是圖片非同步載入的過程。首先listView在展示資料的時候,
沒展示一條資料就會呼叫getView()一次,在我們進行下拉滑動的時候在新的資料展現出來的時
候我們都是在複用上一個item(也就是最頂部的item在不被可見的item),這時候的item還沒
有被回收也就是裡面的資料也沒有回收舊被我們直接拿來使用了,這樣會出現三個問題吧:一
,複用了上一個item,資料我們可以更新,但是圖片可能我們更新不了,因為在載入圖片的時
候我們就開啟了執行緒去伺服器請求圖片,但是上一個item的圖片還沒有被回收,我們 在載的
圖片還沒有成功加載出來,這時候就複用了上一個item的圖片;二,複用了上一個item同樣
是圖片沒加載出來,但是由於記憶體的回收,圖片被回收了,就出現了item上面的圖片顯示的
是是黑屏的渲染;三,同樣是複用上一個item由於網路好載入圖片很快,但是在我們快速滑
動的時候就出現了在不斷複用item的時候就出現了圖片載入錯位了。針對以上的問題,
我在專案中做了一下事件,說了這麼多其實可說說的全是廢話吧,最關鍵的就是程式碼的實現。
其實真的來說要解決listView架子圖片出現的問題,我們可以做如下的邏輯,明確一點
就是給listView設定一個標記,也就是setTag(),用url做唯一的標識進行判斷。

//圖片的請求伺服器的工具類

public abstract class NetImageLoad {  
    private ImageView imageView;  
    private Handler handler = new Handler(){  
        public void handleMessage(android.os.Message msg) {  
            Bitmap bitmap = (Bitmap) msg.obj;  
            loadImage(imageView, bitmap);  
        };  
    };  

    public
abstract void loadImage(ImageView imageView,Bitmap bitmap); public void downloadImage(ImageView imageView,final String imgUrl){ this.imageView =imageView; new Thread(){ public void run() { try { URL url = new URL(imgUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5000
); connection.setReadTimeout(5000); InputStream is = connection.getInputStream(); Bitmap bitmap = BitmapFactory.decodeStream(is); sleep(2000); Message message = new Message(); message.obj = bitmap; handler.sendMessage(message); } catch (Exception e) { e.printStackTrace(); } }; }.start(); } }
圖片的載入處理
public class MainActivity extends Activity {  
    private ListView lv;  
    private List<String> urlList;  

    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.activity_main);  

        lv = (ListView) findViewById(R.id.lv);  

        urlList = new ArrayList<String>();  

        for(int i = 0; i < 20; i++){  
            urlList.add(“圖片存放的url地址”);//我使用的是Tomcat伺服器  
        }  

        lv.setAdapter(new MyBaseAdapter());  
    }  

    class MyBaseAdapter extends BaseAdapter{  

        @Override  
        public int getCount() {  
            return urlList.size();  
        }  

        @Override  
        public Object getItem(int position) {  
            return urlList.get(position);  
        }  

        @Override  
        public long getItemId(int position) {  
            return position;  
        }  

        @Override  
        public View getView(final int position, View convertView, ViewGroup parent) {  
            ViewHolder viewHolder = null;  
            if(convertView == null){  
                viewHolder = new ViewHolder();  
                convertView = View.inflate(getApplicationContext(), 
                R.layout.list_item, null);  
                viewHolder.imageView = (ImageView) convertView.findViewById(R.id.iv);  
                convertView.setTag(viewHolder);  
            }else{  
                viewHolder = (ViewHolder) convertView.getTag();  
            }  

            viewHolder.imageView.setTag(urlList.get(position));  
            viewHolder.imageView.setImageResource(R.drawable.ic_launcher);  

            new NetImageLoad() {  
                @Override  
                public void loadImage(ImageView imageView, Bitmap bitmap) {  
                    if(imageView.getTag()!=null && imageView.getTag().equals(urlList.get(position))){  
                        imageView.setImageBitmap(bitmap);  
                    }  
                }  
            }.downloadImage(viewHolder.imageView,urlList.get(position));  

            return convertView;  
        }  
    }  

    class ViewHolder{  
        ImageView imageView;  
    }  
}  
  以上僅供參考,如有哪出有問題請給我留言,我及時更正,歡迎有大牛們指點。讓我們能有更

深的提高,在這裡謝謝那些為android開發提供資源的大牛們!!!!他們在前面的引路
給我們提高技術分享,讓我們不斷的學習,提升自己,謝謝他們,也歡迎夥伴們一起給我
分享,謝謝!!!!!