Charge d'images paresseuse dans ListView

j'utilise un ListView pour afficher des images et des légendes associées à ces images. Je reçois les images sur Internet. Est-il un moyen de chargement différé des images, de sorte que le texte s'affiche, l'INTERFACE utilisateur n'est pas verrouillé et les images sont affichées en tant qu'ils sont téléchargés?

Le nombre total d'images n'est pas fixe.

1766
demandé sur Pehlaj 2009-02-12 18:59:00

30 réponses

voici ce que j'ai créé pour contenir les images que mon application affiche actuellement. S'il vous plaît noter que l'objet "Log" en usage ici est mon emballage personnalisé autour de la classe Log finale à L'intérieur D'Android.

package com.wilson.android.library;

/*
 Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/
import java.io.IOException;

public class DrawableManager {
    private final Map<String, Drawable> drawableMap;

    public DrawableManager() {
        drawableMap = new HashMap<String, Drawable>();
    }

    public Drawable fetchDrawable(String urlString) {
        if (drawableMap.containsKey(urlString)) {
            return drawableMap.get(urlString);
        }

        Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
        try {
            InputStream is = fetch(urlString);
            Drawable drawable = Drawable.createFromStream(is, "src");


            if (drawable != null) {
                drawableMap.put(urlString, drawable);
                Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                        + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                        + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
            } else {
              Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
            }

            return drawable;
        } catch (MalformedURLException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        } catch (IOException e) {
            Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
            return null;
        }
    }

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
        if (drawableMap.containsKey(urlString)) {
            imageView.setImageDrawable(drawableMap.get(urlString));
        }

        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                imageView.setImageDrawable((Drawable) message.obj);
            }
        };

        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
                Drawable drawable = fetchDrawable(urlString);
                Message message = handler.obtainMessage(1, drawable);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }

    private InputStream fetch(String urlString) throws MalformedURLException, IOException {
        DefaultHttpClient httpClient = new DefaultHttpClient();
        HttpGet request = new HttpGet(urlString);
        HttpResponse response = httpClient.execute(request);
        return response.getEntity().getContent();
    }
}
1030
répondu James A Wilson 2012-11-22 19:17:38

j'ai fait une simple démo d'une liste paresseuse (situé à GitHub) avec des images. Il peut être utile à quelqu'un. Il télécharge des images dans le fil de fond. Les Images sont mises en cache sur une carte SD et en mémoire. L'implémentation du cache est très simple et suffit pour la démo. Je décode les images avec insamples afin de réduire la consommation de mémoire. J'essaie aussi de gérer les vues recyclées correctement.

Alt text

993
répondu Fedor 2014-08-28 23:16:51

je recommande open source instrument Universel Chargeur d'Image . Il est à l'origine basé sur le projet de Fedor Vlasov LazyList et a été considérablement améliorée depuis.

  • Multithread chargement de l'image
  • possibilité d'un large Réglage de la configuration D'ImageLoader (exécuteurs thread, downlaoder, decoder, mémoire et cache disque, options d'affichage d'image, et autres))
  • possibilité de mise en cache de l'image en mémoire et / ou sur le système de fichiers de l'appareil (ou carte SD)
  • possibilité d '" écouter "processus de chargement
  • possibilité de personnaliser chaque appel d'image d'affichage avec des options séparées
  • soutien Widget
  • Android 2.0+ support

536
répondu NOSTRA 2014-08-28 23:19:24

Multithreading For Performance , un tutoriel de Gilles Debunne.

C'est du blog des Développeurs Android. Le code suivant est utilisé:

  • AsyncTasks .
  • dur, dur, de taille limitée, FIFO cache .
  • Un doux, facilement garbage collect -ed cache.
  • Un espace réservé Drawable pendant que vous téléchargez.

enter image description here

150
répondu Thomas Ahle 2014-03-13 11:45:30

mise à jour: notez que cette réponse est assez inefficace maintenant. Le collecteur de déchets agit agressivement sur SoftReference et WeakReference, de sorte que ce code n'est pas adapté pour les nouvelles applications. (au lieu de cela, essayez des bibliothèques comme Chargeur Universel D'Image suggéré dans d'autres réponses.)

merci à James pour le code, et Bao-Long pour la suggestion d'utiliser SoftReference. J'ai implémenté les changements de SoftReference sur le code de James. Malheureusement, mes images ont été ramassées trop rapidement à cause de différences de couleurs. Dans mon cas, c'était bien sans les trucs de SoftReference, parce que ma taille de liste est limitée et mes images sont petites.

Il ya une discussion d'Il ya un an en ce qui concerne les Softréférences sur les groupes google: lien vers le fil . Comme solution au ramassage trop précoce des ordures, ils suggèrent la possibilité de régler manuellement la taille du tas de VM en utilisant dalvik.système.VMRuntime.setMinimumHeapSize(), qui n'est pas très attrayant pour moi.

public DrawableManager() {
    drawableMap = new HashMap<String, SoftReference<Drawable>>();
}

public Drawable fetchDrawable(String urlString) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null)
            return drawable;
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "image url:" + urlString);
    try {
        InputStream is = fetch(urlString);
        Drawable drawable = Drawable.createFromStream(is, "src");
        drawableRef = new SoftReference<Drawable>(drawable);
        drawableMap.put(urlString, drawableRef);
        if (Constants.LOGGING) Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
                + drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
                + drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
        return drawableRef.get();
    } catch (MalformedURLException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    } catch (IOException e) {
        if (Constants.LOGGING) Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
        return null;
    }
}

public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
    SoftReference<Drawable> drawableRef = drawableMap.get(urlString);
    if (drawableRef != null) {
        Drawable drawable = drawableRef.get();
        if (drawable != null) {
            imageView.setImageDrawable(drawableRef.get());
            return;
        }
        // Reference has expired so remove the key from drawableMap
        drawableMap.remove(urlString);
    }

    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            imageView.setImageDrawable((Drawable) message.obj);
        }
    };

    Thread thread = new Thread() {
        @Override
        public void run() {
            //TODO : set imageView to a "pending" image
            Drawable drawable = fetchDrawable(urlString);
            Message message = handler.obtainMessage(1, drawable);
            handler.sendMessage(message);
        }
    };
    thread.start();
}
104
répondu TalkLittle 2013-07-22 00:17:58

Picasso

utilisez la bibliothèque Picasso de Jake Wharton. (Une bibliothèque parfaite de lecture D'image du développeur D'ActionBarSherlock)

une puissante bibliothèque de téléchargement d'image et de mise en cache pour Android.

Les Images

ajoutent un contexte et un flair visuel indispensables aux applications Android. Picasso permet de charger des images sans tracas dans votre application-souvent en une seule ligne de code!

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

de nombreux pièges courants du chargement d'image sur Android sont gérés automatiquement par Picasso:

gestion du recyclage D'ImageView et de l'annulation du téléchargement dans un adaptateur. Transformations d'image Complexes avec utilisation minimale de la mémoire. Mise en cache automatique de la mémoire et du disque.

Picasso Jake de Wharton Bibliothèque

Glide

Glide est une ouverture rapide et efficace source cadre de gestion des Médias pour Android qui enveloppe le décodage des médias, la mémoire et la mise en cache disque, et la mise en commun des ressources dans une interface simple et facile à utiliser.

Glide prend en charge la récupération, le décodage et l'affichage d'images vidéo, d'images et de GIFs animés. Glide inclut une api flexible qui permet aux développeurs de se connecter à presque n'importe quelle pile réseau. Par défaut, Glide utilise une pile personnalisée basée sur HttpUrlConnection, mais inclut également des bibliothèques utilitaires connectées à la volée de Google. la bibliothèque OkHttp de projet ou Square à la place.

Glide.with(this).load("http://goo.gl/h8qOq7").into(imageView);

Glide se concentre principalement sur le fait de faire défiler n'importe quelle sorte d'une liste d'images aussi lisse et rapide que possible, mais Glide est également efficace pour presque tous les cas où vous avez besoin de récupérer, redimensionner, et afficher une image à distance.

Glisse Image De Chargement De La Bibliothèque

fresque de Facebook

fresque est un système puissant pour afficher des images dans les applications Android.

Fresco s'occupe du chargement et de l'affichage des images, donc vous n'avez pas à le faire. Il chargera des images du réseau, du stockage local, ou des ressources locales, et affichera un conteneur jusqu'à ce que l'image soit arrivée. Il a deux niveaux de cache; un en mémoire et un autre dans le stockage interne.

Fresque Github

Dans Android 4.x et plus bas, fresco met images dans une région spéciale de la mémoire Android. Cela permet à votre application de fonctionner plus rapidement - et de souffrir le redouté OutOfMemoryError beaucoup moins souvent.

Fresque De La Documentation

88
répondu Ashwin S Ashok 2015-08-11 18:02:34

chargeur haute performance-après examen des méthodes suggérées ici, J'ai utilisé solution de Ben avec quelques modifications -

  1. "

  2. utiliser SoftReference est génial, mais il rend l'image mise en cache à supprimer trop souvent, donc j'ai ajouté une liste de liens qui contient des références d'images, empêchant l'image d'être supprimée, jusqu'à ce qu'elle atteigne une taille prédéfinie

  3. pour ouvrir l'entrée j'ai utilisé java.net.URLConnection qui me permet d'utiliser le cache web (vous devez d'abord définir un cache de réponse, mais c'est une autre histoire)

mon code:

import java.util.Map; 
import java.util.HashMap; 
import java.util.LinkedList; 
import java.util.Collections; 
import java.util.WeakHashMap; 
import java.lang.ref.SoftReference; 
import java.util.concurrent.Executors; 
import java.util.concurrent.ExecutorService; 
import android.graphics.drawable.Drawable;
import android.widget.ImageView;
import android.os.Handler;
import android.os.Message;
import java.io.InputStream;
import java.net.MalformedURLException; 
import java.io.IOException; 
import java.net.URL;
import java.net.URLConnection;

public class DrawableBackgroundDownloader {    

private final Map<String, SoftReference<Drawable>> mCache = new HashMap<String, SoftReference<Drawable>>();   
private final LinkedList <Drawable> mChacheController = new LinkedList <Drawable> ();
private ExecutorService mThreadPool;  
private final Map<ImageView, String> mImageViews = Collections.synchronizedMap(new WeakHashMap<ImageView, String>());  

public static int MAX_CACHE_SIZE = 80; 
public int THREAD_POOL_SIZE = 3;

/**
 * Constructor
 */
public DrawableBackgroundDownloader() {  
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);  
}  


/**
 * Clears all instance data and stops running threads
 */
public void Reset() {
    ExecutorService oldThreadPool = mThreadPool;
    mThreadPool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
    oldThreadPool.shutdownNow();

    mChacheController.clear();
    mCache.clear();
    mImageViews.clear();
}  

public void loadDrawable(final String url, final ImageView imageView,Drawable placeholder) {  
    mImageViews.put(imageView, url);  
    Drawable drawable = getDrawableFromCache(url);  

    // check in UI thread, so no concurrency issues  
    if (drawable != null) {  
        //Log.d(null, "Item loaded from mCache: " + url);  
        imageView.setImageDrawable(drawable);  
    } else {  
        imageView.setImageDrawable(placeholder);  
        queueJob(url, imageView, placeholder);  
    }  
} 


private Drawable getDrawableFromCache(String url) {  
    if (mCache.containsKey(url)) {  
        return mCache.get(url).get();  
    }  

    return null;  
}

private synchronized void putDrawableInCache(String url,Drawable drawable) {  
    int chacheControllerSize = mChacheController.size();
    if (chacheControllerSize > MAX_CACHE_SIZE) 
        mChacheController.subList(0, MAX_CACHE_SIZE/2).clear();

    mChacheController.addLast(drawable);
    mCache.put(url, new SoftReference<Drawable>(drawable));

}  

private void queueJob(final String url, final ImageView imageView,final Drawable placeholder) {  
    /* Create handler in UI thread. */  
    final Handler handler = new Handler() {  
        @Override  
        public void handleMessage(Message msg) {  
            String tag = mImageViews.get(imageView);  
            if (tag != null && tag.equals(url)) {
                if (imageView.isShown())
                    if (msg.obj != null) {
                        imageView.setImageDrawable((Drawable) msg.obj);  
                    } else {  
                        imageView.setImageDrawable(placeholder);  
                        //Log.d(null, "fail " + url);  
                    } 
            }  
        }  
    };  

    mThreadPool.submit(new Runnable() {  
        @Override  
        public void run() {  
            final Drawable bmp = downloadDrawable(url);
            // if the view is not visible anymore, the image will be ready for next time in cache
            if (imageView.isShown())
            {
                Message message = Message.obtain();  
                message.obj = bmp;
                //Log.d(null, "Item downloaded: " + url);  

                handler.sendMessage(message);
            }
        }  
    });  
}  



private Drawable downloadDrawable(String url) {  
    try {  
        InputStream is = getInputStream(url);

        Drawable drawable = Drawable.createFromStream(is, url);
        putDrawableInCache(url,drawable);  
        return drawable;  

    } catch (MalformedURLException e) {  
        e.printStackTrace();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

    return null;  
}  


private InputStream getInputStream(String urlString) throws MalformedURLException, IOException {
    URL url = new URL(urlString);
    URLConnection connection;
    connection = url.openConnection();
    connection.setUseCaches(true); 
    connection.connect();
    InputStream response = connection.getInputStream();

    return response;
}
}
78
répondu Pinhassi 2012-05-14 09:37:15

j'ai suivi cette formation Android et je pense qu'il fait un excellent travail à télécharger des images sans bloquer l'interface utilisateur principale. Il gère également la mise en cache et le traitement de défilement à travers de nombreuses images: chargement de grands Bitmaps efficacement

76
répondu toobsco42 2013-05-02 21:01:16

1. Picasso permet de charger des images sans tracas dans votre application-souvent en une seule ligne de code!

Use Grad:

implementation 'com.squareup.picasso:picasso:2.71828'

juste une ligne de code!

Picasso.get().load("http://i.imgur.com/DvpvklR.png").into(imageView);

2. Glide Une image de chargement et la mise en cache de la bibliothèque pour Android se concentre sur le défilement en douceur

Use Grad:

repositories {
  mavenCentral() 
  google()
}

dependencies {
   implementation 'com.github.bumptech.glide:glide:4.7.1'
   annotationProcessor 'com.github.bumptech.glide:compiler:4.7.1'
}

/ / pour une vue simple:

  Glide.with(this).load("http://i.imgur.com/DvpvklR.png").into(imageView);

3. fresque est un système puissant pour l'affichage d'images dans Android application.Fresco s'occupe du chargement et de l'affichage des images, donc vous n'avez pas de.

prise en main de la Fresque de la

58
répondu chiragkyada 2018-07-25 10:58:53

j'ai écrit un tutoriel qui explique comment faire chargement différé des images dans une liste. J'aborde en détail les questions du recyclage et de la concurrence. J'utilise également un bassin de filetage fixe pour empêcher le frai beaucoup de filetages.

chargement paresseux d'images dans Listview Tutorial

51
répondu Ben Ruijl 2013-07-04 20:40:56

la façon dont je le fais est en lançant un fil pour télécharger les images à l'arrière-plan et lui remettre un rappel pour chaque élément de la liste. Lorsqu'une image est téléchargée, elle appelle la fonction de rappel qui met à jour la vue pour l'élément de la liste.

cette méthode ne fonctionne pas très bien quand vous recyclez des vues cependant.

39
répondu jasonhudgins 2009-02-12 20:07:14

je veux juste ajouter un autre bon exemple, Adaptateurs XML . Comme il est utilisé par Google et je suis également en utilisant la même logique pour éviter une erreur OutOfMemory.

en gros ce ImageDownloader est votre réponse (qu'il couvre la plupart de vos besoins). Vous pouvez aussi mettre en oeuvre.

31
répondu Arslan 2012-11-22 19:32:50

J'ai utilisé NetworkImageView de la nouvelle bibliothèque Android Volley com.android.volley.toolbox.NetworkImageView , et il semble que cela fonctionne assez bien. Apparemment, c'est la même vue qui est utilisée dans Google Play et d'autres nouvelles applications Google. Certainement la peine de vérifier.

28
répondu droidment 2014-03-16 13:28:38

il s'agit d'un problème commun sur Android qui a été résolu de nombreuses façons par de nombreuses personnes. À mon avis, la meilleure solution que j'ai vu est la bibliothèque relativement nouvelle appelée Picasso . Voici les faits saillants:

27
répondu howettl 2013-10-15 23:22:19

Eh bien, le temps de chargement d'image à partir de L'Internet a de nombreuses solutions. Vous pouvez également utiliser la bibliothèque Android-Requête . Il vous donnera toutes les activité. Assurez-vous de ce que vous voulez faire et lisez la page wiki de la bibliothèque. Et résolvez la restriction de chargement d'image.

C'est mon code:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.row, null);
    }

    ImageView imageview = (ImageView) v.findViewById(R.id.icon);
    AQuery aq = new AQuery(convertView);

    String imageUrl = "http://www.vikispot.com/z/images/vikispot/android-w.png";

    aq.id(imageview).progress(this).image(imageUrl, true, true, 0, 0, new BitmapAjaxCallback() {
        @Override
        public void callback(String url, ImageView iv, Bitmap bm, AjaxStatus status) {
            iv.setImageBitmap(bm);
        }
    ));

    return v;
}

il devrait être résoudre votre problème de chargement paresseux.

25
répondu Rahul Rawat 2015-04-24 21:10:00

je pense que cette question est très populaire parmi les développeurs Android, et il ya beaucoup de bibliothèques qui prétendent résoudre ce problème, mais seulement quelques-uns d'entre eux semble être sur la marque. AQuery est l'une de ces bibliothèques, mais elle est meilleure que la plupart d'entre eux dans tous les aspects et vaut la peine d'essayer pour.

24
répondu Ritesh Kumar Dubey 2014-03-16 13:19:04

regarder Photographe , Applidium est léger SDWebImage (une belle bibliothèque sur iOS) port pour Android. Il prend en charge la mise en cache asynchrone, stocke les URLs erronées, gère bien la concurrence, et des sous-classes utiles sont incluses.

Les requêtes

(et les rapports de bogues) sont également les bienvenues!

20
répondu PatrickNLT 2012-11-02 17:42:16

vous devez essayer ce chargeur universel est le meilleur. J'utilise ceci après avoir fait beaucoup de RnD sur le chargement paresseux .

Universel Chargeur D'Image

Caractéristiques

  • Multithread chargement de l'image (asynchrone ou de synchronisation)
  • large personnalisation de la configuration D'ImageLoader (thread executors, downloader, decoder, memory and disk cache, display image options, etc.)
  • de nombreuses options de personnalisation pour chaque appel d'image d'affichage (empaquetage d'images, commutateur de mise en cache, options de décodage, traitement et affichage Bitmap, etc.)
  • mise en cache de L'Image en mémoire et / ou sur disque (Système de fichiers du périphérique ou carte SD)
  • Écoute processus de chargement (y compris le téléchargement de progrès)

Android 2.0+ support

enter image description here

17
répondu Girish Patel 2015-02-05 12:45:50

DroidParts a ImageFetcher qui nécessite une configuration zéro pour démarrer.

  • utilise un disque et en mémoire moins récemment utilisé (LRU) cache.
  • décode efficacement les images.
  • supporte la modification de bitmaps dans le thread d'arrière-plan.
  • a un fondu croisé simple.
  • a un chargement d'image Rappel de progression.

Clone DroidPartsGram pour un exemple:

Enter image description here

16
répondu yanchenko 2014-03-16 13:26:19

juste un petit conseil pour quelqu'un qui est indécis sur la bibliothèque à utiliser pour les images de chargement paresseux:

il y a quatre façons fondamentales.

  1. DIY => ce n'est Pas la meilleure solution, mais pour quelques images et si vous voulez aller sans avoir à utiliser d'autres bibliothèques

  2. Volley-ball Paresseux de Chargement de la bibliothèque => à Partir de gars à android. Il est beau et tout mais est mal documenté et est donc un problème à l'utilisation.

  3. Picasso: une solution simple qui fonctionne, vous pouvez même spécifier la taille exacte de l'image que vous souhaitez apporter. Il est très simple à utiliser, mais peut-être pas très "performant" pour les applications qui ont à traiter avec énormément d'images.

  4. UIL: Le meilleur moyen de chargement différé des images. Vous pouvez mettre en cache des images (vous avez besoin d'une permission bien sûr), initialiser le chargeur une fois, puis votre travail est fait. La bibliothèque de chargement d'image asynchrone la plus mature que j'ai jamais vue.

16
répondu Bijay Koirala 2015-12-02 05:23:43

Novoda a également un grand lazy image loading library et de nombreuses applications comme Songkick, Podio, SecretDJ et ImageSearch utiliser leur bibliothèque.

leur Bibliothèque est hébergée ici sur Github et ils ont un suivi des problèmes assez actif ainsi. Leur projet semble être assez actif, avec plus de 300+ s'engage au moment de la rédaction de cette réponse.

15
répondu Soham 2013-01-12 11:00:25

Vérifier ma fourchette de LazyList . Fondamentalement, j'améliore le LazyList en retardant l'appel de L'ImageView et créer deux méthodes:

  1. quand vous avez besoin de mettre quelque chose comme "image de chargement..."
  2. lorsque vous avez besoin de montrer l'image téléchargée.

j'ai aussi amélioré L'ImageLoader en implémentant un singleton dans cet objet.

13
répondu Nicolas Jafelle 2014-03-16 13:24:50

tous les codes ci-dessus ont leur propre valeur, mais avec mon expérience personnelle, essayez avec Picasso.

Picasso est une bibliothèque spécifique à cet effet, en fait elle gérera automatiquement le cache et toutes les autres opérations réseau.Vous devrez ajouter une bibliothèque dans votre projet et juste écrire une seule ligne de code pour charger L'image de l'URL distante.

S'il vous plaît visitez ici: http://code.tutsplus.com/tutorials/android-sdk-working-with-picasso--cms-22149

11
répondu Akbar 2015-09-26 18:54:20

je peux recommander une façon différente qui fonctionne comme un charme: interrogation Android.

vous pouvez télécharger que JAR fichier de ici

AQuery androidAQuery = new AQuery(this);

comme exemple:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

c'est très rapide et précis, et en utilisant cela vous pouvez trouver beaucoup plus de fonctionnalités comme l'animation lors du chargement, obtenir un bitmap (si nécessaire), etc.

7
répondu Pratik Dasa 2014-03-16 13:36:00

Donner Aquery un essai. Il a des méthodes étonnamment simples pour charger et mettre en cache des images de façon asynchrone.

7
répondu user2779311 2014-03-16 13:37:22

URLImageViewHelper est une bibliothèque incroyable qui vous aide à le faire.

7
répondu DiegoAlt 2014-03-16 13:37:45

utilisez la bibliothèque glide. Ça a marché pour moi et ça marchera aussi pour ton code.Cela fonctionne aussi bien pour les images que pour les gifs.

ImageView imageView = (ImageView) findViewById(R.id.test_image); 
    GlideDrawableImageViewTarget imagePreview = new GlideDrawableImageViewTarget(imageView);
    Glide
            .with(this)
            .load(url)
            .listener(new RequestListener<String, GlideDrawable>() {
                @Override
                public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {                       
                    return false;
                }

                @Override
                public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
                    return false;
                }
            })
            .into(imagePreview);
}
7
répondu Saket Kumar 2017-03-16 10:11:09

si vous voulez afficher la mise en page Shimmer comme Facebook Il ya une bibliothèque facebok officiel pour cela. FaceBook Shimmer Android

il prend soin de tout, vous avez juste besoin de mettre votre code de conception désiré de manière imbriquée dans le cadre de shimmer. Voici un exemple de code.

<com.facebook.shimmer.ShimmerFrameLayout
     android:id=“@+id/shimmer_view_container”
     android:layout_width=“wrap_content”
     android:layout_height="wrap_content"
     shimmer:duration="1000">

 <here will be your content to display />

</com.facebook.shimmer.ShimmerFrameLayout>

Et voici le code java.

ShimmerFrameLayout shimmerContainer = (ShimmerFrameLayout) findViewById(R.id.shimmer_view_container);
shimmerContainer.startShimmerAnimation();

Ajoutez cette dépendance dans votre fichier gradle.

implementation 'com.facebook.shimmer:shimmer:0.1.0@aar'

voilà à quoi ça ressemble. Shimmer Android screenshot

5
répondu Zankrut Parmar 2018-02-26 05:02:17
public class ImageDownloader {

Map<String, Bitmap> imageCache;

public ImageDownloader() {
    imageCache = new HashMap<String, Bitmap>();

}

// download function
public void download(String url, ImageView imageView) {
    if (cancelPotentialDownload(url, imageView)) {

        // Caching code right here
        String filename = String.valueOf(url.hashCode());
        File f = new File(getCacheDirectory(imageView.getContext()),
                filename);

        // Is the bitmap in our memory cache?
        Bitmap bitmap = null;

        bitmap = (Bitmap) imageCache.get(f.getPath());

        if (bitmap == null) {

            bitmap = BitmapFactory.decodeFile(f.getPath());

            if (bitmap != null) {
                imageCache.put(f.getPath(), bitmap);
            }

        }
        // No? download it
        if (bitmap == null) {
            try {
                BitmapDownloaderTask task = new BitmapDownloaderTask(
                        imageView);
                DownloadedDrawable downloadedDrawable = new DownloadedDrawable(
                        task);
                imageView.setImageDrawable(downloadedDrawable);
                task.execute(url);
            } catch (Exception e) {
                Log.e("Error==>", e.toString());
            }

        } else {
            // Yes? set the image
            imageView.setImageBitmap(bitmap);
        }
    }
}

// cancel a download (internal only)
private static boolean cancelPotentialDownload(String url,
        ImageView imageView) {
    BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);

    if (bitmapDownloaderTask != null) {
        String bitmapUrl = bitmapDownloaderTask.url;
        if ((bitmapUrl == null) || (!bitmapUrl.equals(url))) {
            bitmapDownloaderTask.cancel(true);
        } else {
            // The same URL is already being downloaded.
            return false;
        }
    }
    return true;
}

// gets an existing download if one exists for the imageview
private static BitmapDownloaderTask getBitmapDownloaderTask(
        ImageView imageView) {
    if (imageView != null) {
        Drawable drawable = imageView.getDrawable();
        if (drawable instanceof DownloadedDrawable) {
            DownloadedDrawable downloadedDrawable = (DownloadedDrawable) drawable;
            return downloadedDrawable.getBitmapDownloaderTask();
        }
    }
    return null;
}

// our caching functions
// Find the dir to save cached images
private static File getCacheDirectory(Context context) {
    String sdState = android.os.Environment.getExternalStorageState();
    File cacheDir;

    if (sdState.equals(android.os.Environment.MEDIA_MOUNTED)) {
        File sdDir = android.os.Environment.getExternalStorageDirectory();

        // TODO : Change your diretcory here
        cacheDir = new File(sdDir, "data/ToDo/images");
    } else
        cacheDir = context.getCacheDir();

    if (!cacheDir.exists())
        cacheDir.mkdirs();
    return cacheDir;
}

private void writeFile(Bitmap bmp, File f) {
    FileOutputStream out = null;

    try {
        out = new FileOutputStream(f);
        bmp.compress(Bitmap.CompressFormat.PNG, 80, out);
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        try {
            if (out != null)
                out.close();
        } catch (Exception ex) {
        }
    }
}

// download asynctask
public class BitmapDownloaderTask extends AsyncTask<String, Void, Bitmap> {
    private String url;
    private final WeakReference<ImageView> imageViewReference;

    public BitmapDownloaderTask(ImageView imageView) {
        imageViewReference = new WeakReference<ImageView>(imageView);
    }

    @Override
    // Actual download method, run in the task thread
    protected Bitmap doInBackground(String... params) {
        // params comes from the execute() call: params[0] is the url.
        url = (String) params[0];
        return downloadBitmap(params[0]);
    }

    @Override
    // Once the image is downloaded, associates it to the imageView
    protected void onPostExecute(Bitmap bitmap) {
        if (isCancelled()) {
            bitmap = null;
        }

        if (imageViewReference != null) {
            ImageView imageView = imageViewReference.get();
            BitmapDownloaderTask bitmapDownloaderTask = getBitmapDownloaderTask(imageView);
            // Change bitmap only if this process is still associated with
            // it
            if (this == bitmapDownloaderTask) {
                imageView.setImageBitmap(bitmap);

                // cache the image

                String filename = String.valueOf(url.hashCode());
                File f = new File(
                        getCacheDirectory(imageView.getContext()), filename);

                imageCache.put(f.getPath(), bitmap);

                writeFile(bitmap, f);
            }
        }
    }

}

static class DownloadedDrawable extends ColorDrawable {
    private final WeakReference<BitmapDownloaderTask> bitmapDownloaderTaskReference;

    public DownloadedDrawable(BitmapDownloaderTask bitmapDownloaderTask) {
        super(Color.WHITE);
        bitmapDownloaderTaskReference = new WeakReference<BitmapDownloaderTask>(
                bitmapDownloaderTask);
    }

    public BitmapDownloaderTask getBitmapDownloaderTask() {
        return bitmapDownloaderTaskReference.get();
    }
}

// the actual download code
static Bitmap downloadBitmap(String url) {
    HttpParams params = new BasicHttpParams();
    params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
            HttpVersion.HTTP_1_1);
    HttpClient client = new DefaultHttpClient(params);
    final HttpGet getRequest = new HttpGet(url);

    try {
        HttpResponse response = client.execute(getRequest);
        final int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode != HttpStatus.SC_OK) {
            Log.w("ImageDownloader", "Error " + statusCode
                    + " while retrieving bitmap from " + url);
            return null;
        }

        final HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream inputStream = null;
            try {
                inputStream = entity.getContent();
                final Bitmap bitmap = BitmapFactory
                        .decodeStream(inputStream);
                return bitmap;
            } finally {
                if (inputStream != null) {
                    inputStream.close();
                }
                entity.consumeContent();
            }
        }
    } catch (Exception e) {
        // Could provide a more explicit error message for IOException or
        // IllegalStateException
        getRequest.abort();
        Log.w("ImageDownloader", "Error while retrieving bitmap from "
                + url + e.toString());
    } finally {
        if (client != null) {
            // client.close();
        }
    }
    return null;
 }
}
4
répondu Nikhil Gupta 2013-10-21 12:21:40

j'ai eu ce problème et j'ai implémenté lruCache. Je crois que vous avez besoin de L'API 12 et plus ou utilisez la bibliothèque compatible v4. lurCache est une mémoire rapide, mais elle a aussi un budget, donc si vous êtes inquiet, vous pouvez utiliser un diskcache... Tout est décrit dans cache Bitmaps .

je vais maintenant fournir mon implémentation qui est un singleton j'appelle de n'importe où comme ceci:

//Where the first is a string and the other is a imageview to load.

DownloadImageTask.getInstance().loadBitmap(avatarURL, iv_avatar);

voici le code idéal à mettre en cache et ensuite appeler le ci-dessus dans getView d'un adaptateur lors de la récupération de l'image web:

public class DownloadImageTask {

    private LruCache<String, Bitmap> mMemoryCache;

    /* Create a singleton class to call this from multiple classes */

    private static DownloadImageTask instance = null;

    public static DownloadImageTask getInstance() {
        if (instance == null) {
            instance = new DownloadImageTask();
        }
        return instance;
    }

    //Lock the constructor from public instances
    private DownloadImageTask() {

        // Get max available VM memory, exceeding this amount will throw an
        // OutOfMemory exception. Stored in kilobytes as LruCache takes an
        // int in its constructor.
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);

        // Use 1/8th of the available memory for this memory cache.
        final int cacheSize = maxMemory / 8;

        mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
            @Override
            protected int sizeOf(String key, Bitmap bitmap) {
                // The cache size will be measured in kilobytes rather than
                // number of items.
                return bitmap.getByteCount() / 1024;
            }
        };
    }

    public void loadBitmap(String avatarURL, ImageView imageView) {
        final String imageKey = String.valueOf(avatarURL);

        final Bitmap bitmap = getBitmapFromMemCache(imageKey);
        if (bitmap != null) {
            imageView.setImageBitmap(bitmap);
        } else {
            imageView.setImageResource(R.drawable.ic_launcher);

            new DownloadImageTaskViaWeb(imageView).execute(avatarURL);
        }
    }

    private void addBitmapToMemoryCache(String key, Bitmap bitmap) {
        if (getBitmapFromMemCache(key) == null) {
            mMemoryCache.put(key, bitmap);
        }
    }

    private Bitmap getBitmapFromMemCache(String key) {
        return mMemoryCache.get(key);
    }

    /* A background process that opens a http stream and decodes a web image. */

    class DownloadImageTaskViaWeb extends AsyncTask<String, Void, Bitmap> {
        ImageView bmImage;

        public DownloadImageTaskViaWeb(ImageView bmImage) {
            this.bmImage = bmImage;
        }

        protected Bitmap doInBackground(String... urls) {

            String urldisplay = urls[0];
            Bitmap mIcon = null;
            try {
                InputStream in = new java.net.URL(urldisplay).openStream();
                mIcon = BitmapFactory.decodeStream(in);

            } 
            catch (Exception e) {
                Log.e("Error", e.getMessage());
                e.printStackTrace();
            }

            addBitmapToMemoryCache(String.valueOf(urldisplay), mIcon);

            return mIcon;
        }

        /* After decoding we update the view on the main UI. */
        protected void onPostExecute(Bitmap result) {
            bmImage.setImageBitmap(result);
        }
    }
}
4
répondu j2emanue 2014-03-16 13:34:56