Voici mon code qui saisit toutes les images dans la chaîne html (il est simplifié de l'original, donc j'espère que cela fonctionne):
private HashMap<String, Drawable> mImageCache = new HashMap<String, Drawable>();
private String mDescription = "...your html here...";
private void updateImages(final boolean downloadImages) {
if (mDescription == null) return;
Spanned spanned = Html.fromHtml(mDescription,
new Html.ImageGetter() {
@Override
public Drawable getDrawable(final String source) {
Drawable drawable = mImageCache.get(source);
if (drawable != null) {
return drawable;
} else if (downloadImages) {
new ImageDownloader(new ImageDownloader.ImageDownloadListener() {
@Override
public void onImageDownloadComplete(byte[] bitmapData) {
Drawable drawable = new BitmapDrawable(getResources(),
BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length));
try {
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
} catch (Exception ex) {}
mImageCache.put(source, drawable);
updateImages(false);
}
@Override
public void onImageDownloadFailed(Exception ex) {}
}).execute(source);
}
return null;
}
}, null);
tvDescription.setText(spanned);
}
Donc, fondamentalement, ce qui se passe ici est le ImageGetter fera une demande pour chaque image dans la description html. Si cette image ne figure pas dans le tableau mImageCache et que downloadImages est true, nous exécutons une tâche asynchrone pour télécharger cette image. Une fois terminé, nous ajoutons le drawable dans la hashmap, puis nous faisons à nouveau appel à cette méthode (mais avec downloadImages comme faux, donc nous ne risquons pas une boucle infinie), où l'image pourra être saisie avec le deuxième essai.
Et avec cela, vous aurez besoin de la classe ImageDownloader que je:
public class ImageDownloader extends AsyncTask {
public interface ImageDownloadListener {
public void onImageDownloadComplete(byte[] bitmapData);
public void onImageDownloadFailed(Exception ex);
}
private ImageDownloadListener mListener = null;
public ImageDownloader(ImageDownloadListener listener) {
mListener = listener;
}
protected Object doInBackground(Object... urls) {
String url = (String)urls[0];
ByteArrayOutputStream baos = null;
InputStream mIn = null;
try {
mIn = new java.net.URL(url).openStream();
int bytesRead;
byte[] buffer = new byte[64];
baos = new ByteArrayOutputStream();
while ((bytesRead = mIn.read(buffer)) > 0) {
if (isCancelled()) return null;
baos.write(buffer, 0, bytesRead);
}
return new AsyncTaskResult<byte[]>(baos.toByteArray());
} catch (Exception ex) {
return new AsyncTaskResult<byte[]>(ex);
}
finally {
Quick.close(mIn);
Quick.close(baos);
}
}
protected void onPostExecute(Object objResult) {
AsyncTaskResult<byte[]> result = (AsyncTaskResult<byte[]>)objResult;
if (isCancelled() || result == null) return;
if (result.getError() != null) {
mListener.onImageDownloadFailed(result.getError());
}
else if (mListener != null)
mListener.onImageDownloadComplete(result.getResult());
}
}
Pouvez-vous partager votre code? Votre solution semble vraiment interessante ... –
Salut, je viens de redéfinir le texte avec le contenu Spanned. Cela déclenchera le ImageGetter à nouveau. – shiami
Je parlais de ImageDownloadAsyncTask (textView, htmlString, source) pourquoi a-t-il besoin de htmlString asparameter? –