2016-07-29 29 views
0

我正在查詢SQLite數據庫並將數據放入列表視圖。其中一個數據庫行包含一個圖像Url字段(也可以是Uri)。來自使用自定義光標適配器閃爍url的圖像

圖像被加載,因爲他們應該,但只要我滾動列表所有的圖像開始閃爍,一些正在改變的地方或顯示在不同的地方。

我已經明白,這種行爲發生是因爲列表視圖重複使用滾動行,但我不知道如何解決這種行爲。此外,我不能在這個項目中使用像畢加索這樣的外部庫。

這裏是我的適配器代碼:

public class FilmsListCustomAdapter extends CursorAdapter { 

    private LayoutInflater cursorInflater; 

    public FilmsListCustomAdapter(Context context, Cursor c, int flags) { 
     super(context, c, flags); 
     cursorInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) { 
     TextView filmTitle = (TextView) view.findViewById(R.id.filmListTitle); 
     TextView filmScore = (TextView) view.findViewById(R.id.filmListScore); 
     ImageView filmImage = (ImageView)view.findViewById(R.id.filmListPoster); 
     ImageView filmSeen = (ImageView)view.findViewById(R.id.filmListSeen); 

     String title = cursor.getString(cursor.getColumnIndex("title")); 
     String score = cursor.getString(cursor.getColumnIndex("score")); 
     String url = cursor.getString(cursor.getColumnIndex("url")); 
     int seen = cursor.getInt(cursor.getColumnIndex("seen")); 

     if(Patterns.WEB_URL.matcher(url).matches()){ 
      LoadImage loadImage = new LoadImage(context,filmImage); 
      loadImage.execute(url); 
     } 
     else{ 
      Bitmap bmp = BitmapFactory.decodeFile(url); 
      CamImage camImage = new CamImage(context,Uri.parse(url)); 
      Bitmap rotetedIm = camImage.rotateCamImage(bmp,url); 
      if(rotetedIm!=null){filmImage.setImageBitmap(Bitmap.createScaledBitmap(rotetedIm, 850, rotetedIm.getHeight(), false));} 
      else{filmImage.setImageResource(R.drawable.no_poster);} 
     } 

     GlobalMethods methods = new GlobalMethods(context); 
     filmTitle.setTypeface(methods.getWalkFont()); 
     filmTitle.setText(title); 
     filmScore.setText(score); 
     if(seen==1){filmSeen.setImageResource(R.drawable.eye);} 
     else{filmSeen.setImageResource(0);} 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup viewGroup) { 
     return cursorInflater.inflate(R.layout.film_row, viewGroup, false); 
    } 
} 
+0

我不明白你爲什麼不想使用畢加索的libabry。使用Picasso或Glide庫來顯示具有存儲圖像功能的圖像,因此無需在列表視圖中下載圖像。這裏是畢加索的鏈接:http://square.github.io/picasso/和For Glide:https://github.com/bumptech/glide – Janak

+0

它不是我不想。這是一個學校項目,他們要求我不會使用外部庫。 –

回答

1

什麼是可能發生的事情是這樣的:

  • 你得到的圖像的網頁網址與排隊的AsyncTask下載它的ImageView

  • 您滾動並回收ImageView

  • 此番ImageView得到本地URL,這樣你就可以立即

  • 前面排隊AsyncTask完成,並加載了你只是把

關鍵的形象,現在不相關的圖像清除這個問題是爲了確保在回收ImageView後取消任務。你可以這樣做的一種方法是在ImageView的標籤中加入對AsyncTask的引用。當你得到一個回收的ImageView時,你檢查標籤,看看是否有任務正在進行,並在開始新任務之前取消它。

你應該看看這篇文章在Android開發者博客,它會解釋一下這個問題了一點,如何解決它:

Multithreading For Performance | Android Developers Blog

我想,這文章寫回來的時候AsyncTask小號是更改爲並行線程運行,因爲他們談論的任務完成不按順序。他們已經恢復到串行執行狀態,所以我不認爲這個部分已經適用了,但這個概念是相似的,因爲你的本地圖像的立即加載就像一個不按順序執行的任務。其他

兩件事情我會考慮:

  • getView,隨時調用imageView.setImageBitmap(null)首先在回收ImageView以清除任何剩餘的圖像。我喜歡用一個非常中性的灰色位圖來初始化ImageView,這表示「圖像加載」狀態。使用AsyncTask解碼本地文件以及檢索Web文件。我敢打賭,當你這樣做時,你的列表滾動看起來會更順暢。

相關問題