Domanda

Sto usando a ListView per visualizzare alcune immagini e didascalie associate a tali immagini.Ricevo le immagini da Internet.Esiste un modo per caricare lentamente le immagini in modo che mentre viene visualizzato il testo, l'interfaccia utente non sia bloccata e le immagini vengano visualizzate mentre vengono scaricate?

Il numero totale di immagini non è fisso.

È stato utile?

Soluzione

Ecco quello che ho creato per contenere le immagini che la mia app è attualmente la visualizzazione. Si prega di notare che l'oggetto "Log" in uso qui è il mio wrapper personalizzato intorno alla classe Log finale all'interno di 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();
    }
}

Altri suggerimenti

una semplice demo di una lista pigro (che si trova a GitHub) con le immagini.

  

Utilizzo di base

ImageLoader imageLoader=new ImageLoader(context); ...
imageLoader.DisplayImage(url, imageView); 
     

Non dimenticate di aggiungere il   dopo le autorizzazioni alla AndroidManifest.xml:

 <uses-permission android:name="android.permission.INTERNET"/>
 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> Please
     

creare una sola istanza di ImageLoader e riutilizzarlo tutto intorno alla vostra   applicazione. Questa immagine caching modo sarà molto più efficiente.

Può essere utile a qualcuno. Si scarica immagini in thread in background. Le immagini vengono memorizzati nella cache su una scheda SD e nella memoria. L'implementazione della cache è molto semplice ed è appena sufficiente per la demo. Decodifico le immagini con inSampleSize per ridurre il consumo di memoria. Cerco anche di gestire correttamente vista riciclati.

text Alt

Vi consiglio strumento open source universale Loader Immagine . Si originariamente basato su progetto di Fedor Vlasov lazylist ed è stata notevolmente migliorata da allora.

  • multithread caricamento delle immagini
  • Possibilità di configurazione sintonizzazione ampio di ImageLoader (esecutori filo, downlaoder, decoder, memoria e della cache del disco, le opzioni di immagine di visualizzazione, e altri)
  • Possibilità di immagine memorizzazione nella cache in memoria e / o nel file sysytem (o scheda SD) del dispositivo
  • Possibilità di "ascoltare" processo di caricamento
  • Possibilità di personalizzare ogni chiamata immagine di visualizzazione con opzioni separate
  • Supporto Widget
  • Supporto Android 2.0 +

Multithreading Per prestazioni , un tutorial di Gilles Debunne.

Questo è da Android Developers Blog. Il codice suggerito utilizza:

  • AsyncTasks.
  • Un disco, dimensioni limitate, FIFO cache.
  • A, facilmente cache di garbage collect-ed morbida.
  • A segnaposto Drawable mentre si scarica.

entrare descrizione dell'immagine qui

Aggiornamento: Si noti che questa risposta è abbastanza inefficace ora. Il garbage collector agisce in modo aggressivo sul SoftReference e WeakReference, quindi questo codice non è adatto per nuove applicazioni. (Invece, provare librerie come Caricatore universale Immagine suggerito in altre risposte.)

Grazie a James per il codice, e Bao-Long per il suggerimento di utilizzare SoftReference. Ho implementato le modifiche SoftReference sul codice di James'. Purtroppo SoftReferences causato le mie immagini di essere garbage collection troppo in fretta. Nel mio caso è stato bene anche senza la roba SoftReference, perché la mia dimensione elenco è limitato e le mie immagini sono di piccole dimensioni.

C'è una discussione rispetto a un anno fa, per quanto riguarda i SoftReferences sui gruppi di Google: collegamento in filo . Come soluzione alla raccolta dei rifiuti troppo presto, suggeriscono la possibilità di impostare manualmente la dimensione heap VM usando dalvik.system.VMRuntime.setMinimumHeapSize (), che non è molto interessante per me.

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();
}

Picasso

Usa la Biblioteca Picasso di Jake Wharton.(Una libreria Perfect ImageLoading dallo sviluppatore di ActionBarSherlock)

Una potente libreria per il download e la memorizzazione nella cache di immagini per Android.

Le immagini aggiungono contesto ed eleganza visiva tanto necessari alle applicazioni Android.Picasso consente il caricamento delle immagini senza problemi nella tua applicazione, spesso in una riga di codice!

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

Molte trappole comuni del caricamento delle immagini su Android vengono gestite automaticamente da Picasso:

Gestione del riciclo di ImageView e dell'annullamento del download in un adattatore.Trasformazioni di immagini complesse con un utilizzo minimo di memoria.Memoria automatica e memorizzazione nella cache del disco.

La Biblioteca di Picasso Jake Wharton

Scivolare

Glide è un framework di gestione multimediale open source veloce ed efficiente per Android che racchiude la decodifica multimediale, la memorizzazione nella cache della memoria e del disco e il pooling delle risorse in un'interfaccia semplice e facile da usare.

Glide supporta il recupero, la decodifica e la visualizzazione di fermi video, immagini e GIF animate.Glide include un'API flessibile che consente agli sviluppatori di collegarsi a quasi tutti gli stack di rete.Per impostazione predefinita, Glide utilizza uno stack personalizzato basato su HttpUrlConnection, ma include anche librerie di utilità collegate al progetto Volley di Google o alla libreria OkHttp di Square.

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

L'obiettivo principale di Glide è rendere lo scorrimento di qualsiasi tipo di elenco di immagini il più fluido e veloce possibile, ma Glide è efficace anche per quasi tutti i casi in cui è necessario recuperare, ridimensionare e visualizzare un'immagine remota.

Libreria di caricamento immagini a scorrimento

Affresco di Facebook

Fresco è un potente sistema per visualizzare immagini nelle applicazioni Android.

Fresco si occupa del caricamento e della visualizzazione delle immagini, quindi non devi farlo tu.Caricherà le immagini dalla rete, dall'archiviazione locale o dalle risorse locali e visualizzerà un segnaposto fino all'arrivo dell'immagine.Ha due livelli di cache;uno in memoria e un altro nella memoria interna.

Affresco Github

In Android 4.x e versioni precedenti, Fresco inserisce le immagini in una regione speciale della memoria Android.Ciò consente alla tua applicazione di funzionare più velocemente e di soffrire del temuto OutOfMemoryError molto meno spesso.

Documentazione dell'affresco

alte prestazioni loader - dopo aver esaminato i metodi suggeriti qui, Ho usato soluzione di Ben con alcune modifiche -

  1. mi sono reso conto che lavorare con drawable è più veloce che con le bitmap così I utilizza drawable invece

  2. Uso SoftReference è grande, ma rende l'immagine memorizzata nella cache da eliminare troppo spesso, così ho aggiunto una lista collegata che contiene immagini riferimenti, impedendo l'immagine da eliminare, fino a raggiungere una dimensione predefinita

  3. Per aprire l'InputStream ho usato java.net.URLConnection che mi permette di usare la cache web (è necessario impostare prima una cache di risposta, ma questa è un'altra storia)

Il mio codice:

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

Ho seguito questa formazione Android e penso che fa un ottimo lavoro a scaricare le immagini senza bloccare l'utente principale. Si occupa anche di caching e si occupano di scorrere molte immagini: Caricamento bitmap di grandi dimensioni in modo efficiente

1. Picasso consente una il caricamento delle immagini senza problemi nell'applicazione, spesso in una sola riga di codice!

Usa Gradle:

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

Una sola riga di codice!

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

2. Glide un caricamento delle immagini e la biblioteca di caching per Android focalizzata sulla scorrimento continuo

Usa Gradle:

repositories {
  mavenCentral() 
  google()
}

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

// Per una semplice visione:

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

3. affresco è un potente sistema per la visualizzazione di immagini in Android    applications.Fresco si prende cura di caricamento delle immagini e la visualizzazione, in modo da non avere   a.

Guida introduttiva di Affresco

Ho scritto un tutorial che spiega come fare lazy-caricamento delle immagini in una lista. Vado in qualche dettaglio sui problemi del riciclo e la concorrenza. Io uso anche un pool di thread fisso per impedire la deposizione delle uova un sacco di fili.

pigro caricamento delle immagini in Listview Tutorial

Il modo in cui lo faccio è con il lancio di un thread per scaricare le immagini in background e consegnarlo un callback per ogni elemento della lista. Quando un'immagine è finito di scaricare chiama il callback che aggiorna la vista per la voce di elenco.

Questo metodo non funziona molto bene quando si sta riciclando vista però.

Voglio solo aggiungere un altro buon esempio, XML Adattatori . Come è è utilizzato da Google e sto anche utilizzando la stessa logica per evitare un errore OutOfMemory.

questo ImageDownloader è la vostra risposta ( in quanto copre la maggior parte delle vostre esigenze). Alcuni si può anche implementare in questo.

Sono stato utilizzando NetworkImageView dal nuovo com.android.volley.toolbox.NetworkImageView Android Volley Biblioteca, e sembra funzionare abbastanza bene. A quanto pare, questa è la stessa vista che viene utilizzato in Google Play e altre nuove applicazioni di Google. Sicuramente vale la pena di verificare.

Questo è un problema comune su Android che è stato risolto in molti modi da molte persone. A mio parere la soluzione migliore che ho visto è la relativamente nuova libreria chiamata Picasso . Ecco i punti salienti:

  • Open source, ma guidato da Jake Wharton di ActionBarSherlock fama.
  • in modo asincrono caricare le immagini da risorse di rete o app con una sola riga di codice
  • Riconoscimento automatico ListView
  • disco automatico e la memoria cache di
  • Può fare trasformazioni personalizzate
  • Un sacco di opzioni configurabili
  • Super semplice API
  • aggiornato frequenti

Bene, il tempo di caricamento delle immagini da Internet ha molte soluzioni. Si può anche utilizzare il Android-Query . Vi darà tutte le attività necessarie. Assicurarsi che ciò che si vuole fare e leggere la pagina della libreria wiki. E risolvere la restrizione caricamento delle immagini.

Questo è il mio codice:

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

Dovrebbe essere possibile risolvere il problema lazy loading.

Credo che questo problema è molto popolare tra gli sviluppatori di Android, e ci sono un sacco di tali librerie che pretende di risolvere il problema, ma solo alcuni di loro sembra essere sul punto. AQuery è uno di questi biblioteca, ma è meglio che la maggior parte di loro in tutti gli aspetti e vale la pena di provare per.

È necessario provare questo caricatore universale è la cosa migliore. Sto usando questo dopo fatto molti RnD sul caricamento pigro.

Universale Immagine Loader

Caratteristiche

  • multithread caricamento delle immagini (asincrona o sync)
  • Ampia personalizzazione della configurazione di ImageLoader (esecutori filo, downloader, decoder, la memoria e cache del disco, Opzioni di visualizzazione di immagini, ecc.)
  • Molte opzioni di personalizzazione per ogni chiamata immagine di visualizzazione (immagini stub, interruttore caching, opzioni di decodifica, di elaborazione e la visualizzazione bitmap, ecc.)
  • Immagine caching in memoria e / o su disco (file system del dispositivo o nella scheda SD)
  • Ascolto processo di caricamento (compresi i progressi download)

Android 2.0+ supporto

entrare descrizione dell'immagine qui

Date un'occhiata al SDWebImage leggero di Applidium (una bella libreria su iOS) porta ad Android, Shutterbug . Supporta il caching asincrono, negozi falliti URL, gestisce bene la concorrenza, e disponibile sottoclassi sono inclusi.

richieste Pull (e segnalazioni di bug) sono i benvenuti, troppo!

DroidParts ha ImageFetcher che richiede una configurazione a zero per iniziare.

  • Utilizza un disco e in memoria meno recente (LRU) cache.
  • decodifica in modo efficiente le immagini.
  • Supporta modificare immagini bitmap in thread in background.
  • Has semplice dissolvenza incrociata.
  • ha un'immagine di avanzamento del caricamento di callback.

DroidPartsGram per un esempio:

Inserire descrizione dell'immagine qui

Un suggerimento veloce per qualcuno che è in indecisione riguardo a ciò che libreria da utilizzare per le immagini pigro-caricamento:

Ci sono quattro modi di base.

  1. Fai da te => Non è la migliore soluzione, ma per un paio di immagini e se si vuole andare senza il fastidio di utilizzare altri librerie

  2. biblioteca lazy loading di Volley => Da ragazzi di Android. E 'bello e tutto, ma è scarsamente documentata e quindi è un problema da usare.

  3. Picasso: Una soluzione semplice che funziona, si può anche specificare l'esatta dimensione dell'immagine che si desidera portare in E 'molto semplice da usare, ma potrebbe non essere molto "performante" per le applicazioni che ha a che fare. quantità humongous di immagini.

  4. UIL: Il modo migliore per caricare le immagini pigri. È possibile memorizzare nella cache le immagini (è necessario il permesso ovviamente), inizializzare il caricatore una volta, quindi avere il vostro lavoro fatto. La libreria più matura asincrono caricamento delle immagini che io abbia mai visto finora.

Novoda ha anche un grande pigro immagine Libreria carico e molte applicazioni come Songkick, Podio, SecretDJ e ImageSearch usare la loro biblioteca.

La loro biblioteca è ospitata qui su Github e hanno un abbastanza attivo problemi inseguitore pure. Il loro progetto sembra essere abbastanza attivo troppo, con oltre 300 + impegna al momento della stesura di questa risposta.

Controlla la forchetta di lazylist . In sostanza, posso migliorare il lazylist ritardando il richiamo della ImageView e di creare due metodi:

  1. Quando avete bisogno di mettere qualcosa come "immagine ..."
  2. Quando è necessario per mostrare l'immagine scaricata.

Ho anche migliorato l'ImageLoader implementando un singoletto in questo oggetto.

Tutti sopra il codice hanno il loro proprio valore, ma con la mia esperienza personale solo dare una prova con Picasso.

Picasso è una libreria appositamente per questo scopo, in realtà sarà gestire la cache e tutte le altre operazioni di rete automatically.You dovrà aggiungere biblioteca nel progetto e basta scrivere una sola riga di codice per caricare un'immagine da URL remoto.

Si prega di visitare qui: http: // codice .tutsplus.com / tutorial / android-sdk-lavoro-con-picasso - CMS-22149

Se si desidera visualizzare il layout di luccichio come Facebook c'è una biblioteca ufficiale di facebook per questo. FaceBook Shimmer Android

Si prende cura di tutto, Hai solo bisogno di inserire il codice disegno desiderato in maniera nidificato nel telaio shimmer. Ecco un codice di esempio.

<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>

Ed ecco il codice Java per esso.

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

Aggiungi questa dipendenza nel file Gradle.

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

Ecco come sembra Shimmer Android screenshot

Utilizzare la libreria glide. Ha funzionato per me e lavorerà per il codice too.It funziona per entrambe le immagini, così come GIF troppo.

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

posso consigliare un modo diverso che funziona come un fascino:. Android Query

È possibile scaricare quel vaso file da qui

AQuery androidAQuery = new AQuery(this);

Per fare un esempio:

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

E 'molto veloce e preciso, e l'utilizzo di questo si può trovare molte più caratteristiche come l'animazione durante il caricamento, ottenendo una bitmap (se necessario), ecc.

Aquery una prova. Ha metodi incredibilmente semplici da caricare e immagini di cache in modo asincrono.

URLImageViewHelper è una straordinaria biblioteca che ti aiuta a farlo.

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

Ho avuto questo problema e implementato LRUCache. Credo che hai bisogno di API 12 e al di sopra o utilizza la libreria compatibilità v4. lurCache è memoria veloce, ma ha anche un bilancio, quindi, se siete preoccupati che si può usare un DISKCACHE ... E 'tutto descritto in Caching bitmap .

Io ora fornire la mia realizzazione che è un Singleton io chiamo da qualsiasi luogo come questo:

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

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

Ecco il codice ideale per memorizzare nella cache e quindi chiamare il suddetto in GetView di un adattatore quando si recuperano l'immagine 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);
        }
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top