Android: Display image in imageview by SimpleAdapter

余生颓废 提交于 2019-12-05 13:30:43

Okay. So I assume here that you insist on using SimpleAdapter. No probem, problem solved, just follow the steps:

First lets create our custom row.xml for our ListView which will consist of only one ImageView.(You can add whatever you like to it later on but now i'll assume that you only wanna load the ImageView)

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="5dp"
        android:layout_marginTop="5dp"
        android:src="@drawable/ic_launcher" />


</RelativeLayout>

Second lets create our custom SimpleAdapter

package com.example.helpstack;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.SimpleAdapter;

public class MySimpleAdapter extends SimpleAdapter {
    private Context mContext;
    public LayoutInflater inflater = null;

    public MySimpleAdapter(Context context,
            List<? extends Map<String, ?>> data, int resource, String[] from,
            int[] to) {
        super(context, data, resource, from, to);
        mContext = context;
        inflater = (LayoutInflater) mContext
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View vi = convertView;
        if (convertView == null)
            vi = inflater.inflate(R.layout.row, null);

        HashMap<String, Object> data = (HashMap<String, Object>) getItem(position);

        new DownloadTask((ImageView) vi.findViewById(R.id.imageView1))
                .execute((String) data.get("uri"));

        return vi;
    }

}

Third lets create our DownloadTask, this class will download the image:

package com.example.helpstack;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.widget.ImageView;

public class DownloadTask extends AsyncTask<String, Void, Boolean> {
    ImageView v;
    String url;
    Bitmap bm;

    public DownloadTask(ImageView v) {
        this.v = v;
    }

    @Override
    protected Boolean doInBackground(String... params) {
        url = params[0];
        bm = loadBitmap(url);
        return true;
    }

    @Override
    protected void onPostExecute(Boolean result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
        v.setImageBitmap(bm);
    }

    public static Bitmap loadBitmap(String url) {
        try {
            URL newurl = new URL(url);
            Bitmap b = BitmapFactory.decodeStream(newurl.openConnection()
                    .getInputStream());
            return b;
        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }
}

Now the DownloadTask is being used from inside the getView() in SimpleAdapter

Fourth lets run our amazing small project from our MainActivity.java

package com.example.helpstack;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;

public class MainActivity extends Activity {
    ListView lv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv = (ListView) findViewById(R.id.listView1);
        List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("uri",
                "http://upload.wikimedia.org/wikipedia/commons/thumb/f/f9/Wiktionary_small.svg/350px-Wiktionary_small.svg.png");
        //here u can add as many uri as u want
        data.add(map);
        MySimpleAdapter adapter = new MySimpleAdapter(MainActivity.this, data,
                R.layout.row, new String[] {}, new int[] {});
        lv.setAdapter(adapter);
    }
}

You can use any image cache library. Example, Picasa, Universal Image Loader..

You can cache the images from the URL and then you can use the images in your app.

You can find the libraries in the following links

http://square.github.io/picasso/ and https://github.com/nostra13/Android-Universal-Image-Loader

You can use multiple thread to download and decode bitmap .please follow this website and try to learn how android Developer use thread pool executer to execute different image in thread. http://developer.android.com/training/multiple-threads/create-threadpool.html

1) To set the image Uri to the ImageView you can use a ViewBinder
You have to implement the abstract class and override setViewValue

2) You can use Picasso to load the images in a background thread and cache them. The setViewValue method would look like this:

boolean setViewValue (View view, Object data, String textRepresentation) {
  if(view.getId() == R.id.imageView1) {
    Picasso.with(view.getContext()).load(textRepresentation).into((ImageView) view);
    return true;
  }
  return false;
}

You return true if you want to take care of the binding. You return false for the default behavior.

3) Set your adapter to use the ViewBinder by calling adapter.setViewBinder(ViewBinder);

for now, my suggestion for you is:
1. download the image from url
2. save it as drawable in the storage
3. set this drawable to the image src of imageview
(I didn't see you do this part of job from your code...)

I suggest you use Universal Image Loader, it uses asynchronous image downloading, caching and displaying, there you can find examples how to implement it. After you do it you dont have to concern about the number of images, or its size.

If you download the project you will find this example that does all the work you want:

/**
 * @author Sergey Tarasevich (nostra13[at]gmail[dot]com)
 */
public class ImageListActivity extends AbsListViewBaseActivity {

    DisplayImageOptions options;

    String[] imageUrls;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ac_image_list);

            // here you get a String array with images URL
        Bundle bundle = getIntent().getExtras();
        imageUrls = bundle.getStringArray(Extra.IMAGES);

        options = new DisplayImageOptions.Builder()
            .showImageOnLoading(R.drawable.ic_stub)
            .showImageForEmptyUri(R.drawable.ic_empty)
            .showImageOnFail(R.drawable.ic_error)
            .cacheInMemory(true)
            .cacheOnDisc(true)
            .considerExifParams(true)
            .displayer(new RoundedBitmapDisplayer(20))
            .build();

        listView = (ListView) findViewById(android.R.id.list);
        ((ListView) listView).setAdapter(new ItemAdapter());
        listView.setOnItemClickListener(new OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                startImagePagerActivity(position);
            }
        });
    }

    @Override
    public void onBackPressed() {
        AnimateFirstDisplayListener.displayedImages.clear();
        super.onBackPressed();
    }
    // it gets the position of listView and opens that image in a new Activity
    private void startImagePagerActivity(int position) {
        Intent intent = new Intent(this, ImagePagerActivity.class);
        intent.putExtra(Extra.IMAGES, imageUrls);
        intent.putExtra(Extra.IMAGE_POSITION, position);
        startActivity(intent);
    }

    class ItemAdapter extends BaseAdapter {

        private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener();

        private class ViewHolder {
            public TextView text;
            public ImageView image;
        }

        @Override
        public int getCount() {
            return imageUrls.length;
        }

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

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

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            View view = convertView;
            final ViewHolder holder;
            if (convertView == null) {
                view = getLayoutInflater().inflate(R.layout.item_list_image, parent, false);
                holder = new ViewHolder();
                holder.text = (TextView) view.findViewById(R.id.text);
                holder.image = (ImageView) view.findViewById(R.id.image);
                view.setTag(holder);
            } else {
                holder = (ViewHolder) view.getTag();
            }

            holder.text.setText("Item " + (position + 1));
                    // here is the place where is loaded the image using Universal ImageLoader , imageUrls[position] is a list of images URL
            imageLoader.displayImage(imageUrls[position], holder.image, options, animateFirstListener);

            return view;
        }
    }

    private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener {

        static final List<String> displayedImages = Collections.synchronizedList(new LinkedList<String>());

        @Override
        public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            if (loadedImage != null) {
                ImageView imageView = (ImageView) view;
                boolean firstDisplay = !displayedImages.contains(imageUri);
                if (firstDisplay) {
                    FadeInBitmapDisplayer.animate(imageView, 500);
                    displayedImages.add(imageUri);
                }
            }
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!