Cuillère Posted July 23, 2010 Share Posted July 23, 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 :) Link to comment Share on other sites More sharing options...
Infernus Posted July 23, 2010 Share Posted July 23, 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. Link to comment Share on other sites More sharing options...
Cuillère Posted July 23, 2010 Author Share Posted July 23, 2010 En dehors de l'adapter ? Dans l'activité qui utilise la listView ? Un exemple du code peut-être ? Link to comment Share on other sites More sharing options...
Cuillère Posted July 23, 2010 Author Share Posted July 23, 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 ? Link to comment Share on other sites More sharing options...
Cuillère Posted July 23, 2010 Author Share Posted July 23, 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); } } } Link to comment Share on other sites More sharing options...
Alocaly Posted July 23, 2010 Share Posted July 23, 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 Link to comment Share on other sites More sharing options...
Recommended Posts
Archived
This topic is now archived and is closed to further replies.