2081 Stimmen

Wie man Bilder in ListView in Android verzögert lädt

Ich verwende eine ListView um einige Bilder und die mit diesen Bildern verbundenen Beschriftungen anzuzeigen. Ich beziehe die Bilder aus dem Internet. Gibt es eine Möglichkeit, Bilder langsam zu laden, so dass die Benutzeroberfläche nicht blockiert wird, während der Text angezeigt wird, und die Bilder so angezeigt werden, wie sie heruntergeladen werden?

Die Gesamtzahl der Bilder ist nicht festgelegt.

13 Stimmen

Sie können verwenden GreenDroids AsyncImageView . Einfach anrufen setUrl .

8 Stimmen

Ich habe es benutzt. Es ist eine wunderbare Umsetzung. Schlechte Nachricht, dass AsyncImageView ist ein Teil eines großen GreenDroid Projekt, das Ihre Anwendung größer machen, auch in dem Fall, alles, was Sie brauchen, ist AsyncImageView. Auch scheint, GreenDroid Projekt ist nicht seit 2011 aktualisiert.

6 Stimmen

Sie können diese Bibliothek auch einmal ausprobieren: Android-http-image-manager die meiner Meinung nach die beste Lösung für asynchrones Laden von Bildern ist.

108voto

Ashwin S Ashok Punkte 3433

Picasso

Verwenden Sie die Picasso-Bibliothek von Jake Wharton. (Eine perfekte ImageLoading Library vom Entwickler von ActionBarSherlock)

Eine leistungsstarke Bibliothek zum Herunterladen und Zwischenspeichern von Bildern für Android.

Bilder verleihen Android-Anwendungen den dringend benötigten Kontext und visuelles Flair. Picasso ermöglicht das mühelose Laden von Bildern in Ihrer Anwendung - oft in einer einzigen Code-Zeile!

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

Viele gängige Probleme beim Laden von Bildern auf Android werden von Picasso automatisch gelöst:

Handhabung von ImageView Recycling und Downloadabbruch in einem Adapter. Komplexe Bildtransformationen mit minimalem Speicherverbrauch. Automatische Zwischenspeicherung von Speicher und Festplatte.

Picasso Jake Wharton's Bibliothek

Gleiten

Glide ist ein schnelles und effizientes Open-Source-Medienverwaltungs-Framework für Android, das Medien-Dekodierung, Speicher- und Festplatten-Caching sowie Ressourcen-Pooling in einer einfachen und benutzerfreundlichen Oberfläche zusammenfasst.

Glide unterstützt das Abrufen, Dekodieren und Anzeigen von Videostandbildern, Bildern und animierten GIFs. Glide verfügt über eine flexible API, die es Entwicklern ermöglicht, nahezu jeden Netzwerk-Stack zu nutzen. Standardmäßig verwendet Glide einen benutzerdefinierten, auf HttpUrlConnection basierenden Stack, enthält aber auch Dienstprogramm-Bibliotheken, die sich stattdessen in das Volley-Projekt von Google oder die OkHttp-Bibliothek von Square einfügen.

Glide.with(this).load("your-url-here").into(imageView);

Das Hauptaugenmerk von Glide liegt darauf, das Scrollen einer Liste von Bildern so reibungslos und schnell wie möglich zu gestalten, aber Glide ist auch für fast alle Fälle geeignet, in denen Sie ein entferntes Bild abrufen, in der Größe verändern und anzeigen müssen.

Glide Image Loading Library

Fresko bei Facebook

Fresco ist ein leistungsstarkes System zur Anzeige von Bildern in Android-Anwendungen.

Fresco kümmert sich um das Laden und Anzeigen der Bilder, so dass Sie das nicht tun müssen. Es lädt Bilder aus dem Netzwerk, aus dem lokalen Speicher oder aus lokalen Ressourcen und zeigt einen Platzhalter an, bis das Bild angekommen ist. Es verfügt über zwei Cache-Ebenen: eine im Arbeitsspeicher und eine weitere im internen Speicher.

Fresco Github

In Android 4.x und niedriger legt Fresco Bilder in einem speziellen Bereich des Android-Speichers ab. Dadurch kann Ihre Anwendung schneller laufen - und der gefürchtete OutOfMemoryError tritt viel seltener auf.

Fresko Dokumentation

88voto

Asaf Pinhassi Punkte 14743

Leistungsstarker Lader - nach Prüfung der hier vorgeschlagenen Methoden, habe ich Bens Lösung mit einigen Änderungen -

  1. Ich erkannte, dass die Arbeit mit drawable ist schneller als mit Bitmaps, so dass ich verwendet drawable statt

  2. Mit SoftReference ist großartig, aber es macht das zwischengespeicherte Bild zu oft gelöscht werden, so fügte ich eine Linked-Liste, die Bilder Referenzen hält, verhindert das Bild gelöscht werden, bis es eine vordefinierte Größe erreicht

  3. Um den InputStream zu öffnen, habe ich java.net.URLConnection benutzt, was mir erlaubt, den Web-Cache zu benutzen (Sie müssen zuerst einen Antwort-Cache einrichten, aber das ist eine andere Geschichte)

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

82voto

Etienne Lawlor Punkte 6851

Ich habe dieses Android-Training absolviert und finde, dass es beim Herunterladen von Bildern hervorragende Arbeit leistet, ohne die Hauptbenutzeroberfläche zu blockieren. Es behandelt auch Caching und Umgang mit Scrollen durch viele Bilder: Effizientes Laden großer Bitmaps

73voto

chiragkyada Punkte 3445

1. Picasso ermöglicht das problemlose Laden von Bildern in Ihrer Anwendung - oft in einer einzigen Codezeile!

Gradle verwenden:

implementation 'com.squareup.picasso:picasso:(insert latest version)'

Nur eine Zeile Code!

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

2. Gleiten Eine Bibliothek zum Laden und Zwischenspeichern von Bildern für Android mit Schwerpunkt auf reibungslosem Scrollen

Gradle verwenden:

repositories {
  mavenCentral() 
  google()
}

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

// Für eine einfache Ansicht:

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

3. Fresko ist ein leistungsstarkes System zur Anzeige von Bildern in Android Fresco kümmert sich um das Laden und Anzeigen von Bildern, so dass Sie sich nicht darum kümmern müssen. müssen.

Erste Schritte mit Fresco

56voto

Ben Ruijl Punkte 4585

Ich habe ein Tutorial geschrieben, in dem ich erkläre, wie man das Lazy-Loading von Bildern in einer Listenansicht durchführt. Ich gehe ausführlich auf die Probleme des Recyclings und der Gleichzeitigkeit ein. Ich verwende auch einen festen Thread-Pool, um zu verhindern, dass eine Menge Threads erzeugt werden.

Lazy loading von Bildern in Listview Tutorial

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X