通过简单的适配器在imageview中显示位图图像

问题描述

| 我正在从URL获取图像。我在列表视图中使用imageview。我想将位图图像列表添加到列表项的每一行中。我使用了SimpleAdapter,但是imageview显示为空白。我的代码在下面!
 ArrayList<HashMap<String,Bitmap>> mylist = new ArrayList<HashMap<String,Bitmap>>();

    Bundle bundle = this.getIntent().getExtras();
     get = bundle.getString(\"name\");

     try{
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost httppost = new HttpPost(\"http://www.propertyhookup.com/mobile/propertylist.PHP\");
            nameValuePairs = new ArrayList<NameValuePair>(1);
            nameValuePairs.add(new BasicNameValuePair(\"zipcode\",get.trim()));
            httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
            HttpResponse response = httpclient.execute(httppost);
            httpentity entity = response.getEntity();
            is = entity.getContent();

    }catch(Exception e){
            Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
    }

  //convert response to string
    try{
            BufferedReader reader = new BufferedReader(new InputStreamReader(is,\"iso-8859-1\"),8);
            StringBuilder sb = new StringBuilder();
            String line = null;
            while ((line = reader.readLine()) != null) {
                    sb.append(line + \"\\n\");
            }
            is.close();
            result=sb.toString();
    }catch(Exception e){
            Toast.makeText(getApplicationContext(),Toast.LENGTH_LONG).show();
    }
    if(result.length()<= 7){
        Toast.makeText(getApplicationContext(),\"No properties for this zipcode or check your zipcode \",Toast.LENGTH_LONG).show();
        //text.setText(\"No properties for this zipcode or check your zipcode\");
    }
    else{
    try{

     jArray = new JSONObject(result);            
    }catch(JSONException e){
        Toast.makeText(getApplicationContext(),Toast.LENGTH_LONG).show();
    }

    //JSONObject json = JSONfunctions.getJSONfromURL(\"http://192.168.1.111/propertyhookup.com/mobile/propertylist.PHP\");

    try{

        JSONArray  earthquakes = jArray.getJSONArray(\"earthquakes\");

        for(int i=0;i<10;i++){                      
            map = new HashMap<String,Bitmap>();
            //HashMap<String,Drawable> map1 = new HashMap<String,Drawable>();

            JSONObject e = earthquakes.getJSONObject(i);



            if(e.getString(\"property_type\").contains(\"1\")) {
                proptype =\"Single Family Home\";
            }else if(e.getString(\"property_type\").contains(\"2\")) {
                proptype=\"Condo\";
            }else if(e.getString(\"property_type\").contains(\"3\")) {
                proptype=\"Townhouse\";
            }
            if(e.getString(\"estimated_price\").contains(\"0\")) {
                estimate = \"Not Enough Market Value\";
                //estimat = (TextView) findViewById(R.id.estimat);
                //estimat.setTextColor(Color.rgb(0,23));
            }else {
                estimate = \"$\"+e.getString(\"estimated_price\");
            }

            photo = e.getString(\"photo1\");

            drawable = LoadImageFromWebOperations(photo);

            //text.setimageDrawable(d);

            try
            {
                    aURL = new URL(photo);
            }
            catch (MalformedURLException e1)
            {
                    // Todo Auto-generated catch block
                    e1.printstacktrace();
            }
            URLConnection conn = null;
            try
            {
                    conn = aURL.openConnection();
            }
            catch (IOException e1)
            {
                    // Todo Auto-generated catch block
                    e1.printstacktrace();
            }
            try
            {
                    conn.connect();
            }
            catch (IOException e1)
            {
                    // Todo Auto-generated catch block
                    e1.printstacktrace();
            }
            InputStream is = null;
            try
            {
                    is = conn.getInputStream();
            }
            catch (IOException e1)
            {
                    // Todo Auto-generated catch block
                    e1.printstacktrace();
            }
            BufferedInputStream bis = new
    BufferedInputStream(is,8*1024);
            Bitmap bm = BitmapFactory.decodeStream(bis);

            map.put(photos,bm);
            mylist.add(map);


        }       
    }catch(JSONException e)        {
        Toast.makeText(getApplicationContext(),Toast.LENGTH_LONG).show();
    }



    SimpleAdapter adapter = new SimpleAdapter(this,mylist,R.layout.main4,new String[] { \"percent\",\"propertyid\",\"cityname\",\"statecode\",\"propertytype\",\"footage\",\"bathroom\",\"bedroom\",\"price\",\"estimated\",\"photos\" },new int[] { R.id.percent,R.id.property_id,R.id.city_name,R.id.state_code,R.id.prop_type,R.id.foot,R.id.bath,R.id.bed,R.id.list,R.id.estimat,R.id.image});
    setlistadapter(adapter);
    

解决方法

        我认为是因为您正在从Web下载图像,并且需要在ASYNC中执行这些操作,才能看到无痛的threth下载图像,然后刷新图像视图。     ,        基本上,简单的适配器会自动将一些资源ID或URI绑定到行布局的imageview。 但是它不支持位图。 这是一个问题,因为每个需要管理位图的人都知道,我们经常必须减小图片的大小,以防止内存不足的异常。 但是,如果要将图像添加到listView中,则仅提供URI就无法减小图像的大小。所以这是解决方案: 我修改了simpleAdapter使其能够处理位图。 将该类添加到您的项目中,并使用它代替simpleAdapter。 然后,不传递图像的URI或ressourceId,而是传递Bitmap! 以下是代码:
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.graphics.Bitmap;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Checkable;
import android.widget.ImageView;
import android.widget.SimpleAdapter;
import android.widget.TextView;



public class ExtendedSimpleAdapter extends SimpleAdapter{
    List<? extends Map<String,?>> map; // if fails to compile,replace with List<HashMap<String,Object>> map
    String[] from;
    int layout;
    int[] to;
    Context context;
    LayoutInflater mInflater;
    public ExtendedSimpleAdapter(Context context,List<? extends Map<String,?>> data,// if fails to compile,do the same replacement as above on this line
            int resource,String[] from,int[] to) { 
        super(context,data,resource,from,to);
        layout = resource;
        map = data;
        this.from = from;
        this.to = to;
        this.context = context;
    }


@Override
public View getView(int position,View convertView,ViewGroup parent) {
    mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    return this.createViewFromResource(position,convertView,parent,layout);
}

private View createViewFromResource(int position,ViewGroup parent,int resource) {
    View v;
    if (convertView == null) {
        v = mInflater.inflate(resource,false);
    } else {
        v = convertView;
    }

    this.bindView(position,v);

    return v;
}


private void bindView(int position,View view) {
    final Map dataSet = map.get(position);
    if (dataSet == null) {
        return;
    }

    final ViewBinder binder = super.getViewBinder();
    final int count = to.length;

    for (int i = 0; i < count; i++) {
        final View v = view.findViewById(to[i]);
        if (v != null) {
            final Object data = dataSet.get(from[i]);
            String text = data == null ? \"\" : data.toString();
            if (text == null) {
                text = \"\";
            }

            boolean bound = false;
            if (binder != null) {
                bound = binder.setViewValue(v,text);
            }

            if (!bound) {
                if (v instanceof Checkable) {
                    if (data instanceof Boolean) {
                        ((Checkable) v).setChecked((Boolean) data);
                    } else if (v instanceof TextView) {
                        // Note: keep the instanceof TextView check at the bottom of these
                        // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                        setViewText((TextView) v,text);
                    } else {
                        throw new IllegalStateException(v.getClass().getName() +
                                \" should be bound to a Boolean,not a \" +
                                (data == null ? \"<unknown type>\" : data.getClass()));
                    }
                } else if (v instanceof TextView) {
                    // Note: keep the instanceof TextView check at the bottom of these
                    // ifs since a lot of views are TextViews (e.g. CheckBoxes).
                    setViewText((TextView) v,text);
                } else if (v instanceof ImageView) {
                    if (data instanceof Integer) {
                        setViewImage((ImageView) v,(Integer) data);                            
                    } else if (data instanceof Bitmap){
                        setViewImage((ImageView) v,(Bitmap)data);
                    } else {
                        setViewImage((ImageView) v,text);
                    }
                } else {
                    throw new IllegalStateException(v.getClass().getName() + \" is not a \" +
                            \" view that can be bounds by this SimpleAdapter\");
                }
            }
        }
    }
}



private void setViewImage(ImageView v,Bitmap bmp){
    v.setImageBitmap(bmp);
}



}
此类的行为与原始类(SimpleAdapter)完全相同     ,        最好的方法是创建一个扩展BaseAdapter的类,然后为每个图像实例化一个异步任务(执行后,将位图设置为对应的imageView)。这是从网上下载图片的简单功能:
private Bitmap loadImageFromNetwork(String url) throws MalformedURLException,IOException {
    HttpURLConnection conn = (HttpURLConnection) (new URL(url)).openConnection();
    conn.connect();
    return BitmapFactory.decodeStream(new FlushedInputStream(conn.getInputStream()));
}