来自URL的图像在ListView Scroll上显示和消失

时间:2014-10-24 19:16:47

标签: android

你好我用BaseAdapter填充我的ListView,这里是从url下载图像,然后我在xml行内的ImageView中设置BitMap结果。 它运行正常,但是当我滚动时,图像在不同的地方出现并消失。

这是我的代码:

活动:

public class MyActivity {

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

        lvData = (ListView) findViewById(R.id.listview1);

        AdapterClass adapter = new AdapterClass(this, String[] urls);

        lvData.setAdapter(adapter);
    }
}

适配器:

public class PopularAdapter extends BaseAdapter {

    private String[] mList;
    private LayoutInflater mLayotInflalter;

    public PopularAdapter(Context context, String[] list) {
        mList = list;
        mLayotInflalter = ((Activity) context).getLayoutInflater();
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        WrapperRow wrapper;

        if (convertView == null) {
            convertView = mLayotInflalter.inflate(R.layout.row, null);
            wrapper = new WrapperRow (convertView);

            convertView.setTag(wrapper);
        } else
            wrapper = (WrapperRow ) convertView.getTag();

        // //

        new DownloadImage(wrapper.getImageView()).execute(mList.[position]);

        return convertView;
    }

}

图片下载程序类:

public class DownloadImage extends AsyncTask<String, Void, Bitmap> {
    ImageView bmImage;

    public DownloadImage(ImageView bmImage) {
        this.bmImage = bmImage;
    }

    protected Bitmap doInBackground(String... urls) {
        String urldisplay = urls[0];
        Bitmap mIcon11 = null;
        try {
            InputStream in = new java.net.URL(urldisplay).openStream();
            mIcon11 = BitmapFactory.decodeStream(in);

        } catch (Exception e) {
            Log.e("Error", e.getMessage());
            e.printStackTrace();
        }
        return mIcon11;
    }

    protected void onPostExecute(Bitmap result) {
        bmImage.setImageBitmap(result);
    }
}
你能帮帮我吗? :d

1 个答案:

答案 0 :(得分:3)

这是因为视图在ListView中被回收。 This回答很好地解释了回收机制的工作原理。现在进入你的案例,每当在你的适配器中调用getView时,你就会启动一个新的AsyncTask,它在给定的url下载图像并将其设置在WrapperRow中的imageView中。

让我们看看为什么视图会闪烁。考虑到你有一个包装行 - wr1,wr2,wr3 .... wr8,它们被listView循环使用(我随意选择用8行解释.listView可以使用更少或更多)。一旦getView第一次被调用,你就会给包装行(wr1)充气,然后将其传递给下载图像&amp;的AsyncTask。然后设置它。现在滚动列表,并且对于视图wr2到wr8进行相同的处理,并且在进一步滚动时,是时候回收视图并且wr1再次发挥作用。你开始另一个asyncTask来下载图像,但是你从未清除过imageView(它现在已经保存了第一个图像),当任务完成下载时,它会在imageview中设置新图像,这就是当你的图像消失而新的图像时出现。当您滚动列表时,您会看到所有行重复发生这种情况!!

您可以使用PicassoUIL之类的任何库,但如果您想要启动自己的实现,请记住这些内容

  • 不要在asyncTasks中坚持使用强大的视图引用(这会阻止GC中的活动实例,即使它被破坏导致内存泄漏)
  • 每当你启动一个新的asyncTask时,请确保取消之前仍然适用于此视图的asyncTask(如果有的话)
  • 使用缓存(内存和磁盘)
  • 总是更好