【问题标题】:Displaying bitmap image in imageview by simple adapter通过简单的适配器在 imageview 中显示位图图像
【发布时间】:2011-06-13 07:02:10
【问题描述】:

我从一个网址获取图像。我在列表视图中使用图像视图。我想将位图图像列表添加到列表项的每一行中。我使用了 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(), e.getMessage(), 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(), e.getMessage(), 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, 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(),e.getMessage(), 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);

【问题讨论】:

    标签: android listview imageview simpleadapter


    【解决方案1】:

    基本上,简单的适配器会自动将一些资源 ID 或 URI 绑定到行布局的图像视图。 但它不支持位图。

    这是一个问题,因为每个必须管理位图的人都知道,我们经常必须减小图片的大小以防止出现 outOfMemory 异常。 但是如果你想将图片添加到listView中,如果你只提供URI,你就无法减小图片的大小。所以这是解决方案:

    我已经修改了 simpleAdapter 以便能够处理位图。 将此类添加到您的项目中,并使用它来代替 simpleAdapter。 然后,不要传递图像的 URI 或 ressourceId,而是传递位图!

    下面是代码:

    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, View convertView,
            ViewGroup parent, int resource) {
        View v;
        if (convertView == null) {
            v = mInflater.inflate(resource, parent, 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, data, 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) 完全相同

    【讨论】:

    • 我尝试在 autocompletetextview 中使用您的代码来显示带有文本的图像,但我无法使其工作。您能否提供一个示例,或者甚至可以在 autocompletetextview 中使用它?
    • 感谢您的贡献。提示:您的构造函数与 SimpleAdapter 的不匹配。这样我们就不能只在现有代码中将 SimpleAdapter 更改为 ExtendedSimpleAdapter。你可以改进它。 (例如:对我来说,我需要将构造函数从 List 更改为 List 以便它可以工作)
    • 你好莱昂纳多。你是对的,欢迎你。我将在我的答案中将代码 List 更改为代码 List extends Map> 正如我刚刚在 Android L SimpleAdapter 源代码中看到的那样。 subash,对不起,我之前没有看到你的问题,如果我能提供任何帮助,请告诉我。
    • 自从我离开 Android/Java 世界已经一年了,我不确定我所做的修改是否会编译。应该,但如果有人能确认我的代码的这个新版本正在运行,我将不胜感激。
    • 如何在listview中使用这个类?
    【解决方案2】:

    我认为是因为您正在从网络下载图像,您需要在 ASYNC 中执行这些操作,查看无痛 thrething 下载图像,然后刷新图像视图。

    【讨论】:

    • 请给我一个例子,如何执行我上面的代码通过简单的适配器添加图像。或者如何将图像显示到我的图像视图中。我是安卓新手,请帮帮我!!
    【解决方案3】:

    最好的方法是创建一个扩展 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()));
    }
    

    【讨论】:

    • 我的问题不在于下载图像。在我上面的代码中,我将从 url 获取的位图图像添加到 simpleadapter 中,以便在带有 imageview 的列表视图中显示。但是当我运行代码时,图像视图是空的。我能做些什么呢
    • R.id.image 是 ImageView 吗?试试这个:code SimpleAdapter adapter = new SimpleAdapter(this, mylist , R.layout.main4, new String[] { "percent","propertyid", "cityname", "statecode", "propertytype", "footage" , “浴室”, “卧室”, “价格”, “估计”, “照片” }, 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}); setListAdapter(adapter);code "to" 列表中的前 N ​​个视图被赋予 "from" 参数中前 N 列的值。
    • 是的。R.id.image 只是一个 ImageView。但是你的代码如何为我工作? U 没有在 SimpleAdapter 中声明 ImageView 的 id。
    • 如您所见:link 您只需要声明 textViews。但是为什么不创建一个扩展 BaseAdapter 的类呢? link 但是,您可以调用异步任务并在执行后执行 i.setImageBitmap(image),而不是使用带有图像 ID 的数组。
    猜你喜欢
    • 1970-01-01
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-22
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    相关资源
    最近更新 更多