2012-12-31 20 views
5

Attualmente sto tentando di creare una semplice galleria di immagini come Android Gallery, ora obsoleto. Da questa galleria l'utente può anche navigare verso un semplice editor di immagini selezionando un'immagine dalla galleria. Dopo un sacco di ricerche su Google sono riuscito a trovare uno che è esattamente quello di cui ho bisogno. Inizialmente ho avuto molto successo con questo semplicemente inserendo le immagini nella mia cartella come bitmap compresse. Da allora tuttavia ho trovato this video from Google I/O in cui creano una galleria di immagini e un editor di immagini; simile a quello che sto tentando di creare. Ci sono però due differenze principali tra la mia app e la loro:Impossibile caricare le anteprime in ListView

  • che utilizzano un GridView per la loro galleria e io uso il suddetto HorizontalListView
  • Sto tentando di caricare le immagini solo da un percorso di destinazione specificato non solo tutto immagini sulla scheda SD.

Finora non riesco ad adattare il loro codice al mio poiché nessuna immagine viene caricata nella mia galleria. Come con il video Io uso un AsyncTask per caricare le mie miniature:

private class ThumbnailAsyncTask extends AsyncTask<Long, Void, Bitmap> 
    { 
     //The ImageView we will be adding the thumbnail to 
     private final ImageView mTarget; 

     public ThumbnailAsyncTask(ImageView target) 
     { 
      mTarget = target; 
     } 

     @Override 
     protected Bitmap doInBackground(Long... params) 
     { 
      final long photoID = params[0]; 

      final Bitmap result = MediaStore.Images.Thumbnails.getThumbnail(
        getContentResolver(), photoID, MediaStore.Images.Thumbnails.MINI_KIND, null); 

      return result; 
     } 

     @Override 
     protected void onPreExecute() 
     { 
      mTarget.setTag(this); 
     } 

     @Override 
     protected void onPostExecute(Bitmap result) 
     { 
      if (mTarget.getTag() == this) 
      { 
       mTarget.setImageBitmap(result); 
       mTarget.setTag(null); 
      } 
     } 
} 

e sto usando un CursorAdapter per le immagini nella galleria:

private class PhotoAdapter extends CursorAdapter 
    { 
    public PhotoAdapter(Context context) 
    { 
     super(context, null, false); 
    } 

    @Override 
    public View newView(Context context, Cursor cursor, ViewGroup parent) 
    { 
     return LayoutInflater.from(context).inflate(R.layout.list_item, parent, false); 
    } 

    @Override 
    public void bindView(View view, Context context, Cursor cursor) 
    { 
     final long photoId = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID)); 

     final ImageView imageView = (ImageView) view.findViewById(android.R.id.icon); 

     /* 
     * Cancel any pending thumbnail task, since this view is now bound 
     * to new thumbnail 
     */ 
     final ThumbnailAsyncTask oldTask = (ThumbnailAsyncTask) imageView.getTag(); 

     if (oldTask != null) 
      oldTask.cancel(false);  

     /* 
     * If we arrived here, either cache is disabled or cache miss, so we 
     * need to kick task to load manually 
     */ 
     final ThumbnailAsyncTask task = new ThumbnailAsyncTask(imageView); 
     imageView.setImageBitmap(null); 
     imageView.setTag(task); 
     task.execute(photoId); 
    } 
} 

Con il seguente CursorLoader

final LoaderCallbacks<Cursor> mCursorCallbacks = new LoaderCallbacks<Cursor>() 
      { 
       @Override 
       public Loader<Cursor> onCreateLoader(int id, Bundle args) 
       { 
        final String[] columns = {BaseColumns._ID}; 
        return new CursorLoader(NewProjectActivity.this, 
          Uri.fromFile(new File(mTargetPath)), columns, null, null, 
          MediaStore.Images.Media.DATE_ADDED + " DESC"); 
       } 

       @Override 
       public void onLoadFinished(Loader<Cursor> loader, Cursor data) 
       { 
        mAdapter.swapCursor(data); 
       } 

       @Override 
       public void onLoaderReset(Loader<Cursor> loader) 
       { 
        mAdapter.swapCursor(null); 
       } 
      }; 

    getLoaderManager().initLoader(LOADER_CURSOR, null, mCursorCallbacks); 

Qualche idea sul perché nessuna delle mie immagini sta caricando?

risposta

2

Il problema di base qui è, il metodo bindView() non attende il risultato di asynctask. È necessario notificare la visualizzazione elenco quando alcuni dei suoi contenuti vengono modificati.

È possibile effettuare le seguenti modifiche.

1) Modificare task.execute(photoId); a task.execute(photoId).get(); questo forzerà il vostro metodo bindView() per attendere fino a ottenere l'immagine. Questo approccio non è consigliabile ma ti aiuterà a capire il problema esatto.

O

2) In onPost() di asynctask, invalida vecchio contenuto del vostro visualizzazione elenco e cercare di ricaricarlo con nuovi contenuti.

mAdapter.notifyDataSetChanged(); 
mAdapter.notifyDataSetInvalidated(); 

O

3) Personalmente suggerisco di terminare tutte le operazioni di rete prima (cioè le immagini che vanno a prendere) modificando la tua struttura del codice e poi dopo provare a impostare la scheda con i dati da prefetching. Questa non è una soluzione perfetta ma ha funzionato nel mio caso.

+0

Ho provato il tuo primo suggerimento senza alcun risultato, quindi come avrei potuto implementare il tuo secondo suggerimento? Dovrei semplicemente chiamare 'notifyDataSetChanged()'? Mi scuso perché sono un principiante di Android. –

+0

Ho appena finito di riorganizzare il mio codice come suggerito e finalmente ho funzionato. Grazie :) –

Problemi correlati