android gallery view "stutters" con adattatore di carico di image differita

Vorrei creare un adattatore di carico differito per l'utilizzo con un widget Gallery .

Vale a dire getView() restituisce immediatamente un ImageView e in seguito alcuni altri meccanismi chiamano in modo asincrono il suo metodo setImageBitmap() . Lo ho fatto creando un ImageView "pigro" che estende ImageView .

  • import com.google.android.gms.common.api.GoogleApiClient; non può essere risolto
  • Android - Streaming come stream RTMP
  • Android, AsyncTask, controlla lo stato?
  • Android objectAnimator animare backgroundColor di layout
  • Cosa succede a Attività / Servizi quando il telefono passa alla modalità sleep / standby?
  • Come avviare la mia applicazione tramite un URL personalizzato in un'email
  •  public class GalleryImageView extends ImageView { // ... other stuff here ... public void setImage(final Looper looper, final int position) { final Uri uri = looper.get(position); final String path = looper.sharePath(position); new Thread(new Runnable() { @Override public void run() { GalleryBitmap gbmp = new GalleryBitmap(context, uri, path); final Bitmap bmp = gbmp.getBitmap(); // all the work is here handler.post(new Runnable() { @Override public void run() { if (GalleryImageView.this.getTag().equals(uri)) { setImageBitmap(bmp); } } }); } }).start(); } } 

    Quando scorri lentamente nella Gallery , l'image centrale continua a pompare nel centro. È difficile spiegare esattamente, ma è veramente fastidioso. Ho anche provato lo stesso approccio per un adattatore di filatura e funziona perfettamente lì.

    Qualche idea?

  • Ubuntu - Errore: Imansible creare la scheda SD
  • Cancellare la canvas con Canvas.drawColor ()
  • onOptionsItemSelezionato non essere chiamato quando si utilizza la visualizzazione di azione personalizzata
  • Supporto api di Gestione Sip
  • Ottenere l'errore della camera nell'applicazione a barre Zxing
  • Ottieni elenco delle gallerie fotografiche su Android
  • 3 Solutions collect form web for “android gallery view "stutters" con adattatore di carico di image differita”

    La soluzione è quella di implementare un metodo più intelligente di quando recuperare le miniature – è inutile recuperare miniature mentre l'utente sta attraversando l'elenco. Essenzialmente volete qualcosa come quello implementato nell'applicazione di Romain Guy's Shelves .

    Per get la Galleria più retriggers, è necessario implementare una qualche forma di cache in memory e effettuare le seguenti operazioni:

    • Impostare un'image solo se esiste nella cache in memory dal tuo getView . Impostare una bandiera che indica se l'image è stata impostata o se è necessario un download. È inoltre ansible mantenere una memory in una cache sulla scheda SD e nella memory interna e se non è attualmente in inSampleSize mostrare una versione a bassa risoluzione ( inSampleSize impostata a 16 o 8) che sarà visibile solo quando scorri – l'alto res verrà caricato quando l'utente lascia andare e si stabilisce su un'image.
    • Aggiungere un OnItemSelectedListener (e assicurati di call setCallbackDuringFling(false) durante l'initialization) che scarica nuove miniature per tutti gli elementi visibili che richiedono un download solo se il dito degli utenti è in su (è ansible utilizzare getLastVisiblePosition e getLastVisiblePosition per trovare l'intervallo di visualizzazioni visibili )
    • Anche quando l'utente solleva il controllo delle dita per vedere 1. se la posizione selezionata è cambiata da quando l'utente mette il dito verso il basso e se così, 2. se un download è stato avviato a causa del tuo OnItemSelectedListener – se non fosse poi iniziare uno. Ciò è quello di prendere il caso in cui non si verifica il OnItemSelected , e quindi OnItemSelected non fa mai nulla perché è sempre chiamato con il dito giù in questa situazione. Utilizzo un gestore per ritardare l'inizio del download per il tempo di animation della tua galleria (assicuratevi di cancellare tutti i messaggi ritardati inviati a questo gestore each volta onItemSelected viene chiamato onItemSelected o quando si riceve un evento ACTION_DOWN .
    • Dopo aver scaricato un'image, controllare se le visualizzazioni visibili hanno richiesto questa image e aggiornarle

    Inoltre, tenere presente che la componente Gallery predefinita non implementa correttamente View recycling (assume che each posizione nella scheda abbia una vista univoca e che anche il reloopssta di questi elementi venga eliminato quando si scorra lo schermo rendendolo piuttosto inutile). Modifica: non è inutile, ma non è un riloopssta in termini di visite successive / precedenti, ma serve per evitare di call getView per le viste correnti durante le modifiche di layout.

    Ciò significa che il parametro convertView passato al metodo getView più spesso non sarà nullo, il che significa che getView molte viste (che è costoso) – vedere la mia risposta a sostituire il riciclaggio con Gallery with View? per alcuni suggerimenti su questo. (PS: da allora ho modificato il codice – vorrei utilizzare un altro contenitore di riciclaggio per le fasi di layout e le fasi di scorrimento, nella posizione di fase di layout e recuperare le viste nel cestino di layout, in base alla loro posizione e NON call getView se il visto che si ottiene dal bin non è nullo poiché sarà esattamente la stessa vista, anche chiaro il layout riciclare bin dopo la fase di layout – questo rende le cose un po 'più snappier)

    PS: Anche stare molto attenti a quello che fai in OnItemSelected – vale a dire se non è nei posti sopra indicati e quindi cercare di fare il less ansible. Ad esempio ho impostato un text in un TextView sopra la mia Galleria in OnItemSelected . Basta spostare questa chiamata negli stessi punti in cui ho aggiornato le miniature ha fatto una differenza notevole.

    Ho una risposta per te!

    Quando uno dei methods setImage... viene richiamato su ImageView internamente viene richiesto un passaggio di layout, ad esempio, setImageBitmap() come sopra è definito come tale

     public void setImageBitmap(Bitmap bm) { setImageDrawable(new BitmapDrawable(mContext.getResources(), bm)); } 

    che chiama

     public void setImageDrawable(Drawable drawable) { if (mDrawable != drawable) { mResource = 0; mUri = null; updateDrawable(drawable); requestLayout(); //layout requested here! invalidate(); } } 

    che ha l'effetto della galleria "scattando" al centro dell'image che è attualmente più vicina al centro della galleria.

    Quello che ho fatto per impedire questo è che la vista che carichi nella Galleria abbia un'altezza e una width esplicita (in dip s) e che utilizzi una sottoclass ImageView che ignora le richieste di layout. Questo funziona come la galleria ha ancora un passaggio di layout inizialmente, ma non si preoccupa di farlo each volta che un'image nella galleria cambia, che immagino sarebbe WRAP_CONTENT solo accadere se le visualizzazioni della galleria avessero la loro width e l'altezza impostate su WRAP_CONTENT , che non abbiamo . Notare che come invalidate() è ancora chiamato in setImageDrawable() l'image verrà ancora disegnata quando impostata.

    La mia ImageView molto semplice qui sotto!

     /** * This class is useful when loading images (say via a url or file cache) into * ImageView that are contained in dynamic views (Gallerys and ListViews for * example) The width and height should be set explicitly instead of using * wrap_content as any wrapping of content will not be triggered by the image * drawable or bitmap being set (which is normal behaviour for an ImageView) * */ public class ImageViewNoLayoutRefresh extends ImageView { public ImageViewNoLayoutRefresh(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } public ImageViewNoLayoutRefresh(Context context, AttributeSet attrs) { super(context, attrs); } public ImageViewNoLayoutRefresh(Context context) { super(context); } @Override public void requestLayout() { // do nothing - for this to work well this image view should have its dims // set explicitly } } 

    modifica: devo menzionare che gli approcci onItemSelected possono anche funzionare, ma come avrei dovuto agganciare in quello mentre stava avendo fuggendo ho trovato le cose sopra, che penso sia un approccio più flessibile

    Questo potrebbe essere un errore nel metodo onLayout della Galleria. Controlla http://code.google.com/p/android/issues/detail?id=16171 per una soluzione alternativa ansible.

    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.