Pregunta

Estoy usando un ListView para mostrar algunas de las imágenes y leyendas asociadas con esas imágenes.Me estoy poniendo las imágenes de Internet.Hay una manera para que cargue las imágenes de modo que, mientras el texto se muestra la interfaz de usuario no está bloqueado y las imágenes se muestran como se descargan?

El número total de imágenes no es fijo.

¿Fue útil?

Solución

Esto es lo que crea para contener las imágenes que mi aplicación se muestra actualmente. Tenga en cuenta que el objeto "registro" en uso aquí es mi costumbre envoltura alrededor de la clase Log definitiva dentro de 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();
    }
}

Otros consejos

una demostración simple de una lista vago (que se encuentra en GitHub) con imágenes.

  

Uso básico

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

No se olvide de añadir el   permisos siguientes a su AndroidManifest.xml:

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

crear sólo una instancia de ImageLoader y reutilizar todo alrededor de su   solicitud. Este almacenamiento en caché de la imagen manera será mucho más eficiente.

Puede ser útil a alguien. Es capaz de descargar imágenes en el hilo de fondo. Las imágenes se almacenan en caché está en una tarjeta SD y en la memoria. La implementación de caché es muy simple y es suficiente para la demo. Me decodificar imágenes con inSampleSize para reducir el consumo de memoria. También trato de manejar vistas reciclados correctamente.

text Alt

Recomiendo instrumento de código abierto Image Loader universal . Se basa inicialmente en el proyecto de Fedor Vlasov LazyList y se ha mejorado mucho desde entonces.

  • Multithread carga de la imagen
  • Posibilidad de configuración de ancho de ImageLoader sintonía (ejecutores de rosca, downlaoder, decodificador, la memoria y la caché de disco, las opciones de imagen de visualización, y otros)
  • Posibilidad de almacenamiento en caché de la imagen en la memoria y / o en el archivo sysytem (o tarjeta SD) del dispositivo
  • Posibilidad de "escuchar" proceso de carga
  • Posibilidad de personalizar cada llamada imagen de la pantalla con opciones separadas
  • soporte para widgets
  • Soporte Android 2.0+

multihilo Para Rendimiento , un tutorial de Gilles Debunne.

Este es el blog de desarrolladores de Android. El código de las recomendaciones de uso:

  • AsyncTasks.
  • A dura, tamaño limitado, FIFO cache.
  • A blando, fácilmente caché garbage collect-ed.
  • marcador de posición Drawable mientras descargas.

introducir descripción de la imagen aquí

Actualización: Tenga en cuenta que esta respuesta es bastante ineficaz ahora. El recolector de basura actúa agresivamente en SoftReference y WeakReference, por lo que este código no es adecuado para nuevas aplicaciones. (En su lugar, trate de bibliotecas como cargador universal de la imagen sugirió en otras respuestas.)

Gracias a James para el código, y Bao-Long por la sugerencia de utilizar SoftReference. He implementado los cambios en SoftReference código de James. Desafortunadamente SoftReferences causado mis imágenes sean basura recogida demasiado rápido. En mi caso fue muy bien sin la materia SoftReference, porque el tamaño de mi lista es limitado y mis imágenes son pequeñas.

Hay una discusión respecto a un año atrás con respecto a los grupos SoftReferences en Google: enlace para enhebrar . Como una solución a la recolección de basura demasiado temprana, sugieren la posibilidad de establecer manualmente el tamaño del montón máquina virtual mediante dalvik.system.VMRuntime.setMinimumHeapSize (), que no es muy atractivo para mí.

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

Biblioteca Picasso de Uso Jake Wharton. (A ImageLoading Biblioteca perfecto formar el desarrollador de ActionBarSherlock)

Un potente descarga de imágenes y una biblioteca de almacenamiento en caché para Android.

Imágenes añadir contexto muy necesaria y estilo visual para aplicaciones de Android. Picasso permite sin problemas la carga de imágenes en su aplicación, a menudo en una línea de código!

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

Muchos errores comunes de la carga de imágenes en Android son manejados automáticamente por Picasso:

Manejo de reciclaje ImageView y cancelación descarga en un adaptador. transformaciones de imágenes complejas con el uso mínimo de memoria. memoria y almacenamiento en caché de disco automático.

de Picasso Jake Wharton Biblioteca

Glide

Glide es un marco abierto de gestión de medios de origen rápido y eficiente para Android que envuelve decodificación de los medios de comunicación, memoria y almacenamiento en caché de disco, y la puesta en común de recursos en un simple y fácil de usar interfaz.

Glide es compatible con ir a buscar, decodificar y mostrar imágenes de video, imágenes y archivos GIF animados. Glide incluye una API flexible que permite a los desarrolladores el enchufe en a casi cualquier pila de red. Por Glide propuesta utilice una pila basada HttpURLConnection costumbre, sino que también incluye librerías de utilidades que conectar a voleo proyecto de Google o biblioteca OkHttp de la plaza en su lugar.

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

El objetivo principal de Glide es en hacer que el desplazamiento de cualquier tipo de una lista de imágenes como suave y rápido como sea posible, pero Glide también es eficaz para casi cualquier caso en el que tendrá que obtener, cambiar el tamaño, y mostrar una imagen remota.

Glide carga de imágenes Biblioteca

Fresco de Facebook

Fresco es un potente sistema de visualización de imágenes en aplicaciones de Android.

Fresco se ocupa de la carga de imágenes y la pantalla, por lo que no tiene que hacerlo. Se carga imágenes desde la red, almacenamiento local, o los recursos locales, y mostrar un marcador de posición hasta que ha llegado la imagen. Tiene dos niveles de caché; uno en la memoria y otro en el almacenamiento interno.

Fresco Github

En Android 4.x e inferior, Fresco pone imágenes en una región especial de memoria Android. Esto permite que su aplicación se ejecute más rápido -. Y sufrir la temida OutOfMemoryError con mucha menos frecuencia

Fresco Documentación

De alto rendimiento de la cargadora - después de examinar los métodos que aquí se sugiere, He utilizado Ben solución con algunos cambios -

  1. Me di cuenta de que trabajar con dibujables es más rápido que con los mapas de bits así que utiliza dibujables lugar

  2. El uso de SoftReference es genial, pero hace que el caché de la imagen para ser eliminados demasiado a menudo, así que he añadido una lista Enlazada que contiene imágenes de las referencias, la prevención de la imagen para ser eliminados, hasta llegar a un tamaño predefinido

  3. Para abrir el InputStream he usado java.net.URLConnection que me permite utilizar caché de web (es necesario establecer una caché de respuesta de la primera, pero eso es otra historia)

Mi código:

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

He seguido esta Formación Android y creo que hace un excelente trabajo en la descarga de imágenes sin el bloqueo de la interfaz de usuario principal. También maneja el almacenamiento en caché y hacer frente a desplazarse a través de muchas imágenes: Cargando mapas de bits grandes eficientemente

1. Picasso permite sin problemas la carga de imágenes en su aplicación, a menudo en una línea de código!

Uso Gradle:

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

Sólo una línea de código!

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

2. Glide Una carga de imágenes y una biblioteca de almacenamiento en caché para Android se centró en el desplazamiento suave

Uso Gradle:

repositories {
  mavenCentral() 
  google()
}

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

// Para una visión simple:

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

3. fresco es un potente sistema para la visualización de imágenes en Android    applications.Fresco se ocupa de la carga de imágenes y la pantalla, por lo que no tienen   a.

Introducción a Fresco

He escrito un tutorial que explica cómo hacer perezoso de carga de imágenes en una vista de lista. Entro en algunos detalles acerca de los temas de reciclaje y concurrencia. También utilizo un grupo de subprocesos fijo para evitar el desove una gran cantidad de hilos.

Lazy carga de imágenes en Listview Tutorial

La manera de hacerlo es mediante el lanzamiento de un hilo para descargar las imágenes en segundo plano y pasa una llamada de retorno para cada elemento de la lista. Cuando una imagen se termina la descarga se llama a la devolución de llamada que se actualiza la vista del elemento de lista.

Este método no funciona muy bien cuando se está reciclando vistas sin embargo.

Sólo quiero añadir una más buen ejemplo, XML adaptadores . A medida que se es utilizado por Google y yo también estoy usando la misma lógica para evitar un error OutOfMemory.

este ImageDownloader es su respuesta ( ya que cubre la mayor parte de sus necesidades). Algunos también se puede aplicar en eso.

He estado usando NetworkImageView de la nueva com.android.volley.toolbox.NetworkImageView Android Biblioteca del voleo, y parece estar funcionando bastante bien. Al parecer, esta es la misma vista que se utiliza en Google Play y otras nuevas aplicaciones de Google. Merece la pena.

Este es un problema común en Android que ha sido resuelto de muchas maneras por muchas personas. En mi opinión la mejor solución que he visto es la relativamente nueva biblioteca llamada Picasso . Éstos son los aspectos más destacados:

  • El código abierto, pero encabezado por Jake Wharton de ActionBarSherlock fama.
  • cargar de forma asíncrona imágenes desde la red o aplicaciones recursos con una línea de código
  • Detección automática ListView
  • automática de discos y almacenamiento en caché de memoria
  • Puede hacer transformaciones personalizadas
  • Un montón de opciones configurables
  • API super simple
  • Actualizado con frecuencia

Bueno, el tiempo la carga de imágenes a través de Internet tiene muchas soluciones. También puede usar la biblioteca Android en consultas . Se le dará toda la actividad requerida. Asegúrese de que lo que quiere hacer y leer la página de la biblioteca wiki. Y resolver la restricción de la carga de imágenes.

Este es mi código:

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

Debe ser a resolver su problema de carga lenta.

Creo que este tema es muy popular entre los desarrolladores de Android, y hay un montón de tales bibliotecas que pretende resolver este problema, pero sólo unos pocos de ellos parece estar en la marca. AQuery es uno de esos biblioteca, pero es mejor que la mayoría de ellos en todos los aspectos y vale la pena intentarlo.

Tienes que probar este cargador universal es el mejor. Estoy usando esto después de hacer muchas RnD de carga diferida.

universal Image Loader

Características

  • Multithread imagen de carga (asíncrono o sync)
  • Amplia personalización de la configuración de ImageLoader (ejecutores de rosca, descargador, decodificador, la memoria y la caché de disco, las opciones de visualización de imágenes, etc.)
  • Muchas opciones de personalización para cada llamada imagen de la pantalla (imágenes de código auxiliar, interruptor de almacenamiento en caché, Opciones de decodificación, procesamiento y visualización de mapa de bits, etc.)
  • almacenamiento en caché de la imagen en la memoria y / o en el disco (sistema de archivos del dispositivo o la tarjeta SD)
  • Escuchando proceso de carga (incluido el progreso de descarga)

Android 2.0+ apoyo

introducir descripción de la imagen aquí

Tener un vistazo a Shutterbug , SDWebImage ligera de Applidium (una buena biblioteca en iOS) puerto para Android. Es compatible con el almacenamiento en caché asíncrona, tiendas fallaron URL, se maneja bien concurrencia y subclases votos están incluidos.

peticiones de tracción (e informes de errores) son bienvenidos, también!

DroidParts tiene ImageFetcher que requiere configuración cero para empezar.

  • Utiliza un disco y en memoria menos utilizada recientemente (LRU) de caché.
  • decodifica de manera eficiente las imágenes.
  • Es compatible con la modificación de mapas de bits en el subproceso de fondo.
  • ¿Ha sencilla fundido cruzado.
  • tiene una imagen de devolución de llamada de progreso de carga.

Clone DroidPartsGram para un ejemplo:

Enter descripción de la imagen aquí

Sólo un consejo rápido para alguien que está en la indecisión en cuanto a lo que la biblioteca va a utilizar para imágenes perezoso de carga:

Hay cuatro formas básicas.

  1. bricolaje => No es la mejor solución, pero para algunas imágenes y si quieres ir sin la molestia de usar otras bibliotecas

  2. Cargando biblioteca de Lazy voleo => Desde chicos de Android. Es agradable y todo, pero no está bien documentado y por lo tanto es un problema de usar.

  3. Picasso: Una solución sencilla que simplemente funciona, incluso se puede especificar el tamaño de la imagen exacta que desea traer Es muy simple de usar, pero puede que no sea muy "performant" para las aplicaciones que tiene que tratar. gigantescos cantidades de imágenes.

  4. UIL: La mejor manera de cargar imágenes perezosos. Puede almacenar en caché las imágenes (se necesita permiso, por supuesto), inicializar el cargador de una vez, a continuación, han hecho su trabajo. La biblioteca más maduro asíncrono carga de imágenes que he visto hasta ahora.

Novoda también tiene una gran perezoso biblioteca de la carga de imágenes y muchas aplicaciones como Songkick, Podio, SecretDJ y ImageSearch utilizar su biblioteca.

Su biblioteca está alojado aquí en Github y tienen una muy activa problemas de seguimiento también. Su proyecto parece ser bastante activa también, con más de 300 + se compromete en el momento de escribir esta respuesta.

Comprobar el tenedor de LazyList . Básicamente, mejoro la LazyList al retrasar la llamada del ImageView y crear dos métodos:

  1. Cuando tenga que poner algo como "imagen Cargando ..."
  2. Cuando se necesita para mostrar la imagen descargada.

También mejoró la ImageLoader mediante la implementación de un Singleton en este objeto.

Todo el código anterior tiene su propio valor, pero con mi experiencia personal, sólo darle una oportunidad con Picasso.

Picasso es una biblioteca específicamente para este propósito, se administrará en el hecho todas las demás operaciones de la red caché y automatically.You tendrá que añadir la biblioteca en su proyecto y acaba de escribir una sola línea de código para cargar una imagen desde una URL remota.

Por favor, visite aquí: http: // código .tutsplus.com / tutoriales / android-sdk-trabajo-con-Picasso - CMS-22149

Si desea mostrar la disposición del reflejo como Facebook hay una biblioteca oficial de Facebook para eso. FaceBook Shimmer Android

se encarga de todo, usted sólo tiene que poner su código de diseño deseado en forma anidada en el marco de brillo. Aquí hay un código de ejemplo.

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

Y aquí está el código de Java para ello.

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

Añadir esta dependencia en el archivo de Gradle.

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

Aquí es cómo parece pantalla del reflejo de Android

Utilice la biblioteca de planeo. Se trabajó para mí y va a trabajar para su código too.It funciona tanto para imágenes, así como GIF también.

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

Me pueden recomendar una manera diferente que funciona como un encanto:Android De Consulta.

Puedes descargar el JAR archivo de aquí

AQuery androidAQuery = new AQuery(this);

Como un ejemplo:

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

Es muy rápido y preciso, y mediante este se pueden encontrar muchas más características, como la animación al cargar, la obtención de un mapa de bits (si es necesario), etc.

Aquery intentarlo. Cuenta con métodos simples y sorprendentes para cargar imágenes y la memoria caché de forma asíncrona.

URLImageViewHelper es una biblioteca increíble que le ayuda a hacer eso.

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

he tenido este problema e implementé LRUCache. Creo que necesita API 12 y por encima o por utilizar la biblioteca de compatibilidad v4. lurCache es memoria rápida, pero también tiene un presupuesto, por lo que si usted está preocupado acerca de que se puede utilizar un diskcache ... Todo está descrito en Almacenamiento en caché de mapas de bits .

Ahora voy a dar mi aplicación que es una Singleton que llamo desde cualquier lugar de esta manera:

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

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

Aquí está el código ideal para almacenar en caché y luego llamar a la anterior en getView de un adaptador al recuperar la imagen 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);
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top