0

私はJSONを解析し、名前やその他の詳細を表示するために以下のクラスを持っていますが、ここではリストビューで言及しません。
ShowViewActivity.javaSimpleAdapterで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; 
    } 
} 
} 

私は、WebのURLから画像を表示するには、次のImageDownloaderクラスを実装します。

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を拡張しますが、ここで私はSimpleAdapterを拡張して、私の私のカスタムアダプター名myAdapterを使用していますlazyloadの例を参照してください?
このImageLoaderクラスを実装して、Web画像URLから画像ビューを表示するにはどうすればよいですか?

答えて

1

最初のステップは、ImageDownloaderインスタンスを保持することです。インスタンスのために集中管理された場所を使用することをお勧めします。自分の拡張子はApplicationです。そうすれば、一度しか作成する必要はありませんが、必要に応じてどこでも使用できます。さらに、すべての呼び出しでこのオブジェクトを(再)構築すると、提供されたキャッシングは無駄になります。あるいは、私は個人的に前者を好むが、クラスをシングルトンとして設定することもできる。

ImageDownloaderオブジェクトを取得したら、次のようにカスタムアダプターを変更するだけです。 Activity参照を渡す必要があるので、コンストラクタに渡すContext変数のハンドルをmyAdapterのままにしておきます。通常は、実際には実行時に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); 
    } 

    ... 
} 
関連する問題