Autore Topic: Widget, ListView, immagini caricate in un thread separato...  (Letto 1053 volte)

iClaude

  • Visitatore
Widget, ListView, immagini caricate in un thread separato...
« il: 20 Settembre 2014, 11:52:19 CEST »
0
Ho un widget con una ListView dove ogni elemento contiene un'icona 50x50. L'icona viene impostata nel metodo getViewAt(int position) della classe che gestisce il widget attraverso un oggetto RemoteViews.
Ora volendo creare icone diverse per ogni elemento, avrei la necessità di creare un sistema di caricamento delle immagini efficiente, come quello descritto nella documentazione ufficiale Android (caricare immagini della dimensione esatta, utilizzare un thread separato, ecc.), per fare in modo che la ListView scorra in modo fluido.

Per ora sono riuscito a rendere fluido lo scorrimento (se la ListView contiene pochi elementi) decodificando le immagini per le dimensioni esatte delle icone, ma mi manca il passaggio di caricare le immagini in un thread separato. Come è possibile farlo nella classe che gestisce il widget?

Ho provato a passare l'oggetto RemoteViews in un thread separato, ma quando il thread finisce ed utilizzo RemoteViews per impostare le immagini, ho una NullPointerException. Inoltre non credo che questo sia il sistema corretto.

pietmau

  • Visitatore
Re:Widget, ListView, immagini caricate in un thread separato...
« Risposta #1 il: 20 Settembre 2014, 12:06:04 CEST »
0
Ciao iClaude,
mmm sai che non ho mica capito  ;-)
non è che potresti mettere del codice?
Ciao!

iClaude

  • Visitatore
Re:Widget, ListView, immagini caricate in un thread separato...
« Risposta #2 il: 20 Settembre 2014, 12:14:26 CEST »
0
La classe che gestisce il widget è una classe che estende RemoteViewsService, all'interno della quale c'è una classe che implementa RemoteViewsService.RemoteViewsFactory (così come spiegato nella documentazione ufficiale).
Nel metodo getViewAt(int position), che dovrebbe restituire la View ad una data posizione della ListView (in pratica il singolo elemento della lista), imposto l'icona così:

Codice (Java): [Seleziona]
RemoteViews remoteView = new RemoteViews(mioContext.getPackageName(), R.layout.fragment_budget_listview_item);
//...
                    Integer icona = hmIcone.get(voce);
                    Bitmap miaBitmap;
                    if(icona != null) {
                        miaBitmap = decodeSampledBitmapFromResource(mioContext.getResources(), arrIconeId[icona], 50 , 50);
                    }
                    else {
                        miaBitmap = decodeSampledBitmapFromResource(mioContext.getResources(), R.drawable.img_budget, 50 , 50);
                    }
                    remoteView.setImageViewBitmap(R.id.menu_esporta_ivFormato, miaBitmap);

quindi alla fine del metodo:
return remoteView;

Il metodo richiamato è quello che serve per decodificare le immagini per la dimensione esatta:
Codice (Java): [Seleziona]
                public Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) {

                    // First decode with inJustDecodeBounds=true to check dimensions
                    final BitmapFactory.Options options = new BitmapFactory.Options();
                    options.inJustDecodeBounds = true;
                    BitmapFactory.decodeResource(res, resId, options);

                    // Calculate inSampleSize
                    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

                    // Decode bitmap with inSampleSize set
                    options.inJustDecodeBounds = false;
                    return BitmapFactory.decodeResource(res, resId, options);
                }
               
               
                private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) {
                    // Raw height and width of image
                    final int height = options.outHeight;
                    final int width = options.outWidth;
                    int inSampleSize = 1;
               
                    if (height > reqHeight || width > reqWidth) {
               
                        final int halfHeight = height / 2;
                        final int halfWidth = width / 2;
               
                        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
                        // height and width larger than the requested height and width.
                        while ((halfHeight / inSampleSize) > reqHeight
                                && (halfWidth / inSampleSize) > reqWidth) {
                            inSampleSize *= 2;
                        }
                    }
               
                    return inSampleSize;
                }


Il problema è: come spostare il caricamento delle immagini in un thread separato, per fare in modo che la ListView scorra in modo fluido anche quando ha molti elementi?

Offline bradipao

  • Moderatore globale
  • Utente storico
  • *****
  • Post: 4043
  • keep it simple
  • Respect: +567
    • Github
    • Google+
    • bradipao
    • Mostra profilo
  • Dispositivo Android:
    Nexus 5
  • Play Store ID:
    Bradipao
  • Sistema operativo:
    W7
Re:Widget, ListView, immagini caricate in un thread separato...
« Risposta #3 il: 20 Settembre 2014, 12:18:52 CEST »
0
Guarda la libreria Picasso.
NON rispondo a domande nei messaggi privati
Bradipao @ Play Store

pietmau

  • Visitatore
Re:Widget, ListView, immagini caricate in un thread separato...
« Risposta #4 il: 20 Settembre 2014, 12:26:13 CEST »
0
OK se il problema è solo il caricamento dinamico delle immaggini io ti consiglio Universal Image Loader
(che io preferisco a Picasso, ma forse è solo questione di gusti)

Ciao!