Cuillère Posté(e) 23 juillet 2010 Share Posté(e) 23 juillet 2010 Bonjour, J'affiche une liste avec une ImageView et une TextView. Je voudrais télécharger de façon asynchrone les images et les afficher au fur et à mesure qu'elles soient télécharger pour ne pas trop ralentir la navigation entre les fenêtres. J'ai essayé d'utiliser une AsyncTask dans mon adapter mais sans aucun résultat, le code : public class ItemAdapter extends ArrayAdapter{ private static HashMap listImages = new HashMap(); int resource; public ItemAdapter(Context _context, int _resource, List _items) { super(_context, _resource, _items); resource = _resource; } @Override public View getView(int position, View convertView, ViewGroup parent){ LinearLayout newsView; Item item = getItem(position); String strPubDate = item.pubDate; String title = item.getTitle(); String imgUrl = item.getImageUrl(); if (convertView == null){ newsView = new LinearLayout(getContext()); String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, newsView, true); } else { newsView = (LinearLayout) convertView; } TextView txtTitle = (TextView)newsView.findViewById(R.id.txtTitleItemSummary); txtTitle.setText(title); ImageView imgView = (ImageView)newsView.findViewById(R.id.imgViewItemSummary); DownloadImageTask dit = new DownloadImageTask(); dit.execute(imgUrl); /*try{ imgView.setImageDrawable(loadImageFromUrl(imgUrl)); } catch (Exception e) { imgView.setImageResource(R.drawable.icon); }*/ if(!item.pubDate.equals("")){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.FRANCE); try { Date d = sdf.parse(strPubDate); TextView txtDate = (TextView)newsView.findViewById(R.id.txtPubDateElement); txtDate.setText("Publié le " + DateFormat.format("dd/MM/yyyy", d)); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return newsView; } public static Drawable loadImageFromUrl(String url) { if (!listImages.containsValue(url)) { InputStream inputStream; try { inputStream = new URL(url).openStream(); } catch (IOException e) { throw new RuntimeException(e); } Drawable dr = Drawable.createFromStream(inputStream, "src"); listImages.put(url, dr); return dr; } else { return listImages.get(url); } } private class DownloadImageTask extends AsyncTask { protected Drawable doInBackground(String... url) { return loadImageFromUrl(url[0]); } protected void onPostExecute(Drawable result) { } } } Je dois très certainement mal m'y prendre, un peu d'aide serait la bienvenue, merci :) Lien vers le commentaire Partager sur d’autres sites More sharing options...
Infernus Posté(e) 23 juillet 2010 Share Posté(e) 23 juillet 2010 Perso je fais ca en dehors de l'adapter. Toujours est-il qu'il faut dans le onPostExecute ( dans ton cas sinon dans le onProgressUpdate ) demander a l'adapter de rafraichir avec un notifydatasetChanged. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cuillère Posté(e) 23 juillet 2010 Auteur Share Posté(e) 23 juillet 2010 En dehors de l'adapter ? Dans l'activité qui utilise la listView ? Un exemple du code peut-être ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cuillère Posté(e) 23 juillet 2010 Auteur Share Posté(e) 23 juillet 2010 J'ai avancé, mais c'est pas encore tout à fait ça. J'appelle mon AsyncTask pour chaque nouvel item directement dans l'adaptateur, voilà le code : La classe : public class DownloadImageTask extends AsyncTask { private static HashMap listImages = new HashMap(); private static ImageView _imgView; public DownloadImageTask(ImageView imgView){ super(); _imgView = imgView; } protected Drawable doInBackground(String... url) { return loadImageFromUrl(url[0]); } protected void onPostExecute(Drawable result) { try{ _imgView.setImageDrawable(result); } catch (Exception e) { _imgView.setImageResource(R.drawable.ic_menu_info_details); } } public static Drawable loadImageFromUrl(String url) { if (!listImages.containsValue(url)) { InputStream inputStream; try { inputStream = new URL(url).openStream(); } catch (IOException e) { throw new RuntimeException(e); } Drawable dr = Drawable.createFromStream(inputStream, "src"); listImages.put(url, dr); return dr; } else { return listImages.get(url); } } } L'adaptateur : public class ItemAdapter extends ArrayAdapter{ int resource; private static ImageView imgView; public ItemAdapter(Context _context, int _resource, List _items) { super(_context, _resource, _items); resource = _resource; } @Override public View getView(int position, View convertView, ViewGroup parent){ LinearLayout newsView; Item item = getItem(position); String strPubDate = item.pubDate; String title = item.getTitle(); String imgUrl = item.getImageUrl(); if (convertView == null){ newsView = new LinearLayout(getContext()); String inflater = Context.LAYOUT_INFLATER_SERVICE; LayoutInflater vi; vi = (LayoutInflater)getContext().getSystemService(inflater); vi.inflate(resource, newsView, true); } else { newsView = (LinearLayout) convertView; } TextView txtTitle = (TextView)newsView.findViewById(R.id.txtTitleItemSummary); txtTitle.setText(title); imgView = (ImageView)newsView.findViewById(R.id.imgViewItemSummary); imgView.setImageResource(R.drawable.icon); DownloadImageTask dit = new DownloadImageTask(imgView); dit.execute(imgUrl); if(!item.pubDate.equals("")){ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.FRANCE); try { Date d = sdf.parse(strPubDate); TextView txtDate = (TextView)newsView.findViewById(R.id.txtPubDateElement); txtDate.setText("Publié le " + DateFormat.format("dd/MM/yyyy", d)); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return newsView; } Alors, je vois les images apparaitre au fur et à mesure, mais elles vont toutes dans la même ImageView, plus précisement la dernière de ma liste ! Une idée du problème ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cuillère Posté(e) 23 juillet 2010 Auteur Share Posté(e) 23 juillet 2010 J'ai trouvé la solution, voilà le code : public class DownloadImageTask extends AsyncTask { private static HashMap listImages = new HashMap(); private final WeakReference imageViewReference; public DownloadImageTask(ImageView imageView){ super(); imageViewReference = new WeakReference(imageView); } @Override protected Drawable doInBackground(String... url) { Drawable d = loadImageFromUrl(url[0]); publishProgress(d); return d; } @Override protected void onProgressUpdate(Drawable...d){ } @Override protected void onPostExecute(Drawable d) { if (imageViewReference != null) { ImageView imageView = imageViewReference.get(); if (imageView != null) { imageView.setImageDrawable(d); } } } public static Drawable loadImageFromUrl(String url) { if (!listImages.containsValue(url)) { InputStream inputStream; try { inputStream = new URL(url).openStream(); } catch (IOException e) { throw new RuntimeException(e); } Drawable dr = Drawable.createFromStream(inputStream, "src"); listImages.put(url, dr); return dr; } else { return listImages.get(url); } } } Lien vers le commentaire Partager sur d’autres sites More sharing options...
Alocaly Posté(e) 23 juillet 2010 Share Posté(e) 23 juillet 2010 Sinon, si tu veux un code qui devrait etre pas mal, c'est le sujet du dernier article des developpeurs officiels d'Android : http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html Emmanuel / Alocaly Lien vers le commentaire Partager sur d’autres sites More sharing options...
Recommended Posts
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.