在ListView适配器中加载位图/图像

时间:2014-01-21 14:21:16

标签: android android-listview android-asynctask android-adapter android-bitmap

我正在尝试在具有ArrayAdapter的ListView中添加图像。 Fyi,toList()是从迭代器到给定DBObject的列表的转换。

我覆盖View getView()并设置文本视图和图片。

private static class EventAdapter extends ArrayAdapter<DBObject> {      

    public EventAdapter(Context context, int resource, Iterable<DBObject> events) {
        super(context, resource, toList(events));           
    }

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

        View v = convertView;               
        LayoutInflater vi = LayoutInflater.from(getContext());                              
        v = vi.inflate(R.layout.adapter_event_list, null);

        DBObject event = getItem(position);

        if (event != null) {

            //Get the logo if any
            if( ((DBObject)event.get("events")).containsField("logo") ){      

                String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
                ImageView eventLogo = (ImageView) v.findViewById(R.id.eventLogoList);
                new setLogo().execute(logoURL, eventLogo);

            }               
            TextView title= (TextView) v.findViewById(R.id.eventTitleList);             
            title.setText( ((DBObject)event.get("events")).get("title").toString() );               

        }

        return v;
    }

    protected static <T> List<T> toList( Iterable<T> objects ) {
        final ArrayList<T> list = new ArrayList<T>();
        for( T t : objects ) list.add(t);
        return list;
    }
    //setLogo() method here. See below
 }

textview中的文字很好。然而,图像变得混乱。它们似乎加载在列表中的错误位置。代码的路由是:1)从DB(async)获取2)填充ListView 3),同时填充每个图像(第二个异步)。

以上是setLogo() AsyncTask,位于EventAdapter上方:

private class setLogo extends AsyncTask<Object,Void,Bitmap>{

        ImageView eventLogo = null;

        @Override
        protected Bitmap doInBackground(Object...params) {
            try{
                Bitmap eventImage = downloadBitmap((String) params[0]);
                eventLogo =  (ImageView) params[1];
                return eventImage;
            }
            catch(Exception e){
                e.printStackTrace();
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap eventImage) {
            if(eventImage!=null && eventLogo!=null){                    
                eventLogo.setImageBitmap(eventImage);
            }
        }  

}

我这样做(使用Async),我认为这是从网址加载图片的正确方法。我看到了这个post on multithreading,并借用了downloadBitmap()方法。

如上所述,图像被加载到ListView的错误位置。什么是加载它们的强大方法?

另外,在AsyncTask中传递v.findViewById(R.id.eventLogoList)的想法是程序将区分每个适配器的ImageView,但它似乎没有。


更新

在发现导致此混音的问题后,我找到了this SO question

我修改了我的代码,以检查if是否导致问题。

//Get the logo if any               
if( ((DBObject)event.get("events")).containsField("logo") ){                        
        String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
        ImageView eventLogo = (ImageView) row.findViewById(R.id.eventLogoList);

        //new setLogo().execute(logoURL, eventLogo);   

        TextView title= (TextView) row.findViewById(R.id.eventTitleList);
        title.setText( "Shit happens" );    

    }

假设我有40个项目。 Shit happens是在logo字段存在的字段上设置的。如果我向下/向上滚动订单更改并且文本搞砸了。这是因为在循环内部创建的堆栈小于列表的最大值。我猜...我仍在努力。

PS:我发现this easy library异步加载图像而不是DYI东西。


更新2

我添加了一个带有静态网址的其他内容。由于图像加载所需的时间仍然是错位的。

1 个答案:

答案 0 :(得分:0)

我真的会选择像毕加索这样的好图书馆。 它将为您处理所有困难的部分,并且写得非常好。 http://square.github.io/picasso/