0

Ich habe die folgende Klasse, um JSON und Anzeigename und andere Details zu analysieren, die ich hier in listview nicht erwähne.
ShowViewActivity.javaWie wird die ImageLoader-Klasse in SimpleAdapter verwendet, um ImageView von ImageUrl anzuzeigen?

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; 
    } 
} 
} 

Ich möchte folgende ImageDownloader Klasse implementieren von Web-URL anzuzeigen Bild.

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(); 
} 

} 

ich die lazyload Beispiele sehen, die BaseAdapter erstreckt, aber hier bin ich mit meiner meinen benutzerdefinierten Adapternamen myAdapter die SimpleAdapter erstreckt?
Wie implementiert man diese ImageLoader-Klasse, um Bildansicht von Web-Image-URL zu zeigen?

Antwort

1

Der erste Schritt besteht darin, eine Instanz zu erhalten. Ich empfehle Ihnen, einen zentralen Ort für eine Instanz zu verwenden, z. Ihre eigene Erweiterung von Application. Auf diese Weise müssen Sie es nur einmal erstellen, aber überall wo es benötigt wird. Wenn Sie dieses Objekt bei jedem Aufruf (neu) konstruieren, wird das bereitgestellte Caching nur eingeschränkt verwendet. Alternativ könnten Sie die Klasse als Singleton einrichten, obwohl ich persönlich die erste bevorzuge.

Sobald Sie ein Objekt haben, nehmen Sie einfach die Änderungen an Ihrem benutzerdefinierten Adapter wie unten beschrieben vor. Da Sie eine Activity Referenz übergeben müssen, halten Sie ein Handle auf die Context Variable, die Sie in den Konstruktor myAdapter übergeben. Unter normalen Umständen ist dies tatsächlich eine Activity Referenz zur Laufzeit.

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); 
    } 

    ... 
} 
Verwandte Themen