2016-07-29 30 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文件。我敢打赌,当你这样做时,你的列表滚动看起来会更顺畅。

相关问题