ANDROID:在listView中加载异步图片 [英] ANDROID : Load asynchronous pictures in listView

查看:17
本文介绍了ANDROID:在listView中加载异步图片的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想显示一个带有自定义适配器(带有图片和文本)的 ListView.

I 'd like to display a ListView with a customized adapter (with picture and text).

图像是从远程服务器加载的,所以我决定使用 AsyncTask.

Images are loaded from distant servers, so I have decided to use AsyncTask.

其实图片显示效果很好,但是如果我快速向下滚动,1/2秒内显示错误图片(加载后,出现正确图片)

Actually, pictures are well displayed but if I scroll down quickly, a wrong picture is displayed during 1/2 secondes (after loading, correct picture appears)

这是我的适配器代码:

public class GiAdapter extends BaseAdapter {

    private Context mContext;

    private List<SiteStaff> mListAppInfo;
    private HashMap<Integer, ImageView> views;
    private HashMap<String,Bitmap> oldPicts = new  HashMap<String,Bitmap>();
    private LayoutInflater mInflater;
    private boolean auto;

    private final String BUNDLE_URL = "url";
    private final String BUNDLE_BM = "bm";
    private final String BUNDLE_POS = "pos";
    private final String BUNDLE_ID = "id";

    public GiAdapter(Context context, List<SiteStaff> list) {
        mContext = context;
        mListAppInfo = list;
        views = new HashMap<Integer, ImageView>();
        mInflater = LayoutInflater.from(mContext);

    }

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

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

    @Override
    public long getItemId(int position) {
        return mListAppInfo.get(position).getId();
    }

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

        LinearLayout layoutItem;

        // reuse of convertView
        if (convertView == null) {
            layoutItem = (LinearLayout) mInflater.inflate(R.layout.auto_gi, parent, false);
        } else {
            layoutItem = (LinearLayout) convertView;
        }

        // infos for the current element
        SiteStaff entry = mListAppInfo.get(position);

        //set some text fields
        TextView name = (TextView) layoutItem.findViewById(R.id.name);
        TextView size = (TextView) layoutItem.findViewById(R.id.size); 

        name.setText(entry.getName());
        size.setText(entry.getSize());

        // get the imageView for the current object
        ImageView v = (ImageView) layoutItem.findViewById(R.id.gi_image);

        // put infos in bundle and send to the LoadImage class
        Bundle b = new Bundle();

        //url of the pict
        b.putString(BUNDLE_URL, entry.getUrl());

        //position in the listView
        b.putInt(BUNDLE_POS, position);

        //id of the current object
        b.putInt(BUNDLE_ID, entry.getId());

        //put info in the map in order to display in the onPostExecute
        views.put(position, v);

        // thread
        new LoadImage().execute(b);

        return layoutItem;

    }

    //asyncTackClass for loadingpictures
    private class LoadImage extends AsyncTask<Bundle, Void, Bundle> {

        @Override
        protected Bundle doInBackground(Bundle... b) {

            Bitmap bm =null;

            //cache: for better performance, check if url alredy exists
            if(oldPicts.get(b[0].getString(BUNDLE_URL))==null){
                bm = Utils.getBitMapFromUrl(b[0].getString(BUNDLE_URL));
                oldPicts.put(b[0].getString(BUNDLE_URL),bm);
            }else{
                bm = oldPicts.get(b[0].getString(BUNDLE_URL));
            }

            // get info from bundle
            Bundle bundle = new Bundle();
            bundle.putParcelable(BUNDLE_BM, bm);
            bundle.putInt(BUNDLE_POS, b[0].getInt(BUNDLE_POS));

            return bundle;

        }

        @Override
        protected void onPostExecute(Bundle result) {
            super.onPostExecute(result);

            //get picture saved in the map + set
            ImageView view = views.get(result.getInt(BUNDLE_POS));
            Bitmap bm = (Bitmap) result.getParcelable(BUNDLE_BM);

            if (bm != null){ //if bitmap exists...
                view.setImageBitmap(bm);
            }else{ //if not picture, display the default ressource
                view.setImageResource(R.drawable.unknow);
            }

        }

    }

}

谢谢!

推荐答案

这也发生在我身上.我发现在新图像绑定到图像视图之前,旧图像会显示一段时间.在您的情况下,发生的情况是您的正确信息显示在 onPostExecute() 上,这需要一些时间,然后在显示 convertview 中设置的任何数据之前.有两种方法可以解决这个问题,

This happened to me too. What I figured out was that before the new image was getting bound to the imageview, the old one was displayed for a while. In your case, what is happening is that your correct info is showing onPostExecute(), which takes sometime, and before that whatever data was set in the convertview is being shown. There are 2 ways u could mostly fix this,

在您的 getView() 中,将 if{}... else{} 块更改为 just

In your getView(), change the if{}... else{} block to just

layoutItem = (LinearLayout) mInflater.inflate(R.layout.auto_gi, parent, false);

在 getView() 中使用一些占位符图像设置图像视图,直到 onPostExecute() 被调用.

set the imageview with some placeholder image in getView() till onPostExecute() is called.

希望这会有所帮助.

这篇关于ANDROID:在listView中加载异步图片的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆