2012-04-15 82 views
0

我有以下类来解析JSON并显示名称和其他细节,我在这里没有在列表中提到。
ShowViewActivity.java如何使用SimpleAdapter中的ImageLoader类从ImageUrl中显示ImageView?

public class ShowViewActivity extends ListActivity { 

private static String url = "http://example.com/myfile.php"; 
private static final String TAG_ROOT = "root"; 
private static final String TAG_NAME = "name"; 
private static final String TAG_IMAGE = "image"; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    ArrayList<HashMap<String, String>> myList = new ArrayList<HashMap<String, String>>(); 
    JSONParser jParser = new JSONParser(); 
    JSONObject json = jParser.getJSONFromUrl(url); 
    try { 
     root = json.getJSONArray(TAG_ROOT); 
     for (int i = 0; i < root.length(); i++) { 
      JSONObject c = root.getJSONObject(i); 
      String name = c.getString(TAG_NAME); 
      String image = c.getString(TAG_IMAGE); 
      HashMap<String, String> map = new HashMap<String, String>(); 
      map.put(TAG_NAME, name); 
      map.put(TAG_IMAGE, image); 
      myList.add(map); 
     } 
    } catch (JSONException e) { 
     e.printStackTrace(); 
    } 


    myAdapter adapter = new myAdapter(this, myList, R.layout.list_item, 
      new String[] {}, new int[] {}); 

    setListAdapter(adapter); 
    final ListView lv = getListView(); 

    // Launching new screen on Selecting Single ListItem 
    lv.setOnItemClickListener(new OnItemClickListener() { 

     public void onItemClick(AdapterView<?> parent, View view, 
       int position, long id) { 

     } 

    }); 

} 

private class myAdapter extends SimpleAdapter { 

    public myAdapter(Context context, List<? extends Map<String, ?>> data, 
      int resource, String[] from, int[] to) { 
     super(context, data, resource, from, to); 

    } 

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

     if (convertView == null) { 
      convertView = getLayoutInflater().inflate(R.layout.list_item, 
        null); 
     } 

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

     TextView nameTextView = (TextView) convertView 
       .findViewById(R.id.name); 
     ImageView iconImageView = (ImageView) convertView 
       .findViewById(R.id.listicon); 

     String nameString = (String) data.get(TAG_NAME); 
     nameTextView.setText(nameString); 
     String imageUrl = (String) data.get(TAG_IMAGE); 

     return convertView; 
    } 
} 
} 

我要实现以下ImageDownloader类显示来自网站的URL图像。

ImageDownloader.java

public class ImageLoader { 

// the simplest in-memory cache implementation. This should be replaced with 
// something like SoftReference or BitmapOptions.inPurgeable(since 1.6) 
private HashMap<String, Bitmap> cache = new HashMap<String, Bitmap>(); 

private File cacheDir; 

public ImageLoader(Context context) { 
    // Make the background thead low priority. This way it will not affect 
    // the UI performance 
    photoLoaderThread.setPriority(Thread.NORM_PRIORITY - 1); 

    // Find the dir to save cached images 
    if (android.os.Environment.getExternalStorageState().equals(
      android.os.Environment.MEDIA_MOUNTED)) 
     cacheDir = new File(
       android.os.Environment.getExternalStorageDirectory(), 
       "LazyList"); 
    else 
     cacheDir = context.getCacheDir(); 
    if (!cacheDir.exists()) 
     cacheDir.mkdirs(); 
} 

final int stub_id = R.drawable.icon; 

public void DisplayImage(String url, Activity activity, ImageView imageView) { 
    if (cache.containsKey(url)) 
     imageView.setImageBitmap(cache.get(url)); 
    else { 
     queuePhoto(url, activity, imageView); 
     imageView.setImageResource(stub_id); 
    } 
} 

private void queuePhoto(String url, Activity activity, ImageView imageView) { 
    // This ImageView may be used for other images before. So there may be 
    // some old tasks in the queue. We need to discard them. 
    photosQueue.Clean(imageView); 
    PhotoToLoad p = new PhotoToLoad(url, imageView); 
    synchronized (photosQueue.photosToLoad) { 
     photosQueue.photosToLoad.push(p); 
     photosQueue.photosToLoad.notifyAll(); 
    } 

    // start thread if it's not started yet 
    if (photoLoaderThread.getState() == Thread.State.NEW) 
     photoLoaderThread.start(); 
} 

private Bitmap getBitmap(String url) { 
    // I identify images by hashcode. Not a perfect solution, good for the 
    // demo. 
    String filename = String.valueOf(url.hashCode()); 
    File f = new File(cacheDir, filename); 

    // from SD cache 
    Bitmap b = decodeFile(f); 
    if (b != null) 
     return b; 

    // from web 
    try { 
     Bitmap bitmap = null; 
     InputStream is = new URL(url).openStream(); 
     OutputStream os = new FileOutputStream(f); 
     Utils.CopyStream(is, os); 
     os.close(); 
     bitmap = decodeFile(f); 
     return bitmap; 
    } catch (Exception ex) { 
     ex.printStackTrace(); 
     return null; 
    } 
} 

// decodes image and scales it to reduce memory consumption 
private Bitmap decodeFile(File f) { 
    try { 
     // decode image size 
     BitmapFactory.Options o = new BitmapFactory.Options(); 
     o.inJustDecodeBounds = true; 
     BitmapFactory.decodeStream(new FileInputStream(f), null, o); 

     // Find the correct scale value. It should be the power of 2. 
     final int REQUIRED_SIZE = 70; 
     int width_tmp = o.outWidth, height_tmp = o.outHeight; 
     int scale = 1; 
     while (true) { 
      if (width_tmp/2 < REQUIRED_SIZE 
        || height_tmp/2 < REQUIRED_SIZE) 
       break; 
      width_tmp /= 2; 
      height_tmp /= 2; 
      scale++; 
     } 

     // decode with inSampleSize 
     BitmapFactory.Options o2 = new BitmapFactory.Options(); 
     o2.inSampleSize = scale; 
     return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); 
    } catch (FileNotFoundException e) { 
    } 
    return null; 
} 

// Task for the queue 
private class PhotoToLoad { 
    public String url; 
    public ImageView imageView; 

    public PhotoToLoad(String u, ImageView i) { 
     url = u; 
     imageView = i; 
    } 
} 

PhotosQueue photosQueue = new PhotosQueue(); 

public void stopThread() { 
    photoLoaderThread.interrupt(); 
} 

// stores list of photos to download 
class PhotosQueue { 
    private Stack<PhotoToLoad> photosToLoad = new Stack<PhotoToLoad>(); 

    // removes all instances of this ImageView 
    public void Clean(ImageView image) { 
     for (int j = 0; j < photosToLoad.size();) { 
      if (photosToLoad.get(j).imageView == image) 
       photosToLoad.remove(j); 
      else 
       ++j; 
     } 
    } 
} 

class PhotosLoader extends Thread { 
    public void run() { 
     try { 
      while (true) { 
       // thread waits until there are any images to load in the 
       // queue 
       if (photosQueue.photosToLoad.size() == 0) 
        synchronized (photosQueue.photosToLoad) { 
         photosQueue.photosToLoad.wait(); 
        } 
       if (photosQueue.photosToLoad.size() != 0) { 
        PhotoToLoad photoToLoad; 
        synchronized (photosQueue.photosToLoad) { 
         photoToLoad = photosQueue.photosToLoad.pop(); 
        } 
        Bitmap bmp = getBitmap(photoToLoad.url); 
        cache.put(photoToLoad.url, bmp); 
        if (((String) photoToLoad.imageView.getTag()) 
          .equals(photoToLoad.url)) { 
         BitmapDisplayer bd = new BitmapDisplayer(bmp, 
           photoToLoad.imageView); 
         Activity a = (Activity) photoToLoad.imageView 
           .getContext(); 
         a.runOnUiThread(bd); 
        } 
       } 
       if (Thread.interrupted()) 
        break; 
      } 
     } catch (InterruptedException e) { 
      // allow thread to exit 
     } 
    } 
} 

PhotosLoader photoLoaderThread = new PhotosLoader(); 

// Used to display bitmap in the UI thread 
class BitmapDisplayer implements Runnable { 
    Bitmap bitmap; 
    ImageView imageView; 

    public BitmapDisplayer(Bitmap b, ImageView i) { 
     bitmap = b; 
     imageView = i; 
    } 

    public void run() { 
     if (bitmap != null) 
      imageView.setImageBitmap(bitmap); 
     else 
      imageView.setImageResource(stub_id); 
    } 
} 

public void clearCache() { 
    // clear memory cache 
    cache.clear(); 

    // clear SD cache 
    File[] files = cacheDir.listFiles(); 
    for (File f : files) 
     f.delete(); 
} 

} 

我看到延伸BaseAdapter但在这里,我用我的我的自定义适配器名称myAdapter延伸SimpleAdapter的lazyload的例子吗?
如何实现这个ImageLoader类从web图像url显示imageview?

回答

1

第一步是弄个ImageDownloader实例。我建议你为某个实例使用一些集中位置,例如您自己的Application的扩展名。这样您只需创建一次,但在需要的地方随处使用。此外,如果您在每次调用时(重新)构建此对象,则提供的缓存将被限制为无用。另外,你也可以把班级设置为单身人士,尽管我个人更喜欢前者。

一旦您拥有了ImageDownloader对象,只需按照下面所述对自定义适配器进行更改即可。由于您需要传入一个Activity参考,请保留您传入myAdapter的构造函数的Context变量的句柄。在正常情况下,这实际上是运行时的Activity引用。

private class myAdapter extends SimpleAdapter { 

    private Context mContext; 

    public myAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to) { 
     super(context, data, resource, from, to); 
     mContext = context; 

    } 

    ... 

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

     // assuming you have an instance of ImageDownloader here 
     // 
     mImageDownloader.DisplayImage(imageUrl,(Activity)mContext, iconImageView); 
    } 

    ... 
} 
相关问题