IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Composants graphiques Android Discussion :

Problème superpositions d'images dans ListView


Sujet :

Composants graphiques Android

  1. #1
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 281
    Points : 161
    Points
    161
    Par défaut Problème superpositions d'images dans ListView
    Bonjour,

    Je télécharge des données grâce à un webservice que je met dans une ListView.

    Chaque item de ma ListView est composée d'une miniature que je charge dans mon ImageView correspondante grâce à ma classe ImageLoader (voir ci-dessous).

    Mon pproblème est le suivant :

    Lorque je scrolle ma Listview certaines images se superposent sur d'autres pendant un certain moment pour ensuite afficher la bonne.

    Existe-il un moyen pour éviter celà ?


    Mon Adapter

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
     
     
    package com.xxxxxxxxxx;
     
    import java.util.ArrayList;
    import java.util.HashMap;
     
    import com.utils.ImageLoader;
     
     
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Typeface;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.ImageView;
    import android.widget.TextView;
     
    public class ActualiteAdapter extends BaseAdapter
    {
    	ArrayList<HashMap<String, String>> mylist;
    	LayoutInflater	inflater;
    	public Typeface arial_bold, arial;
    	public Activity activity;
    	public ImageLoader imageLoader; 
     
    	public ActualiteAdapter (Context context, Activity a, ArrayList<HashMap<String, String>> myList)
    	{
     
    		inflater = LayoutInflater.from (context);
    		this.mylist = myList;
    		activity = a;
    		imageLoader=new ImageLoader(activity.getApplicationContext());
     
     
    	}
     
     
    	public int getCount ()
    	{
    		return mylist.size ();
    	}
     
    	public Object getItem (int position)
    	{
    		return mylist.get (position);
    	}
     
    	public long getItemId (int position)
    	{
    		// TODO Auto-generated method stub
    		return position;
    	}
     
    	public View getView (int position, View convertView, ViewGroup parent)
    	{
    		ViewHolder holder;
    		if (convertView == null)
    		{
    			holder = new ViewHolder ();
     
     
    			convertView = inflater.inflate (R.layout.actualite_item, null);
     
     
    			holder.titre = (TextView) convertView.findViewById (R.id.titre);
    			holder.extrait = (TextView) convertView.findViewById (R.id.extrait);
    			holder.miniature = (ImageView) convertView.findViewById (R.id.miniature);	
    			convertView.setTag (holder);
    		}
    		else
    		{
    			holder = (ViewHolder) convertView.getTag ();
    		}
     
     
     
    	    holder.titre.setText (mylist.get (position).get("titre").toString ().trim());	
    	    holder.extrait.setText (mylist.get (position).get("detail").toString ().trim().replace("[saut]", ""));
     
    	    imageLoader.DisplayImage(mylist.get(position).get("miniature").toString ().trim(), activity, holder.miniature);
     
    		return convertView;
     
    	}
     
    	public class ViewHolder
    	{
    		ImageView   miniature;
    		TextView	titre;
    		TextView extrait;
     
    	}
     
     
    }
    Ma classe permettant de télécharger les images

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
     
    package com.utils;
     
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URL;
    import java.util.HashMap;
    import java.util.Stack;
     
    import com.xxxxxx.R;
     
    import android.app.Activity;
    import android.content.Context;
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.widget.ImageView;
     
    public class ImageLoader {
     
        //the simplest in-memory cache implementation. This should be replaced with something like SoftReference or BitmapOptions.inPurgeable(since 1.6)
        private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>();
     
        private File cacheDir;
     
        public ImageLoader(Context context){
            //Make the background thead low priority. This way it will not affect the UI performance
            photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1);
     
            //Find the dir to save cached images
            if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED))
                cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),"dirproject");
            else
                cacheDir=context.getCacheDir();
            if(!cacheDir.exists())
                cacheDir.mkdirs();
        }
     
     
        final int stub_id = R.drawable.stub;
     
     
     
        public void DisplayImage(String url, Activity activity, ImageView imageView)
        {
            if(cache.containsKey(url))
            {
     
                imageView.setImageBitmap(cache.get(url));
     
            }
            else
            {
                  queuePhoto(url, activity, imageView);
                  imageView.setBackgroundResource(R.drawable.draw_imageloading);
     
     
     
            }    
        }
     
        private void queuePhoto(String url, Activity activity, ImageView imageView)
        {
            //This ImageView may be used for other images before. So there may be some old tasks in the queue. We need to discard them. 
            photosQueue.Clean(imageView);
            PhotoToLoad p=new PhotoToLoad(url, imageView);
            synchronized(photosQueue.photosToLoad){
                photosQueue.photosToLoad.push(p);
                photosQueue.photosToLoad.notifyAll();
            }
     
            //start thread if it's not started yet
            if(photoLoaderThread.getState()==Thread.State.NEW)
                photoLoaderThread.start();
        }
     
        private Bitmap getBitmap(String url) 
        {
            //I identify images by hashcode. Not a perfect solution, good for the demo.
            String filename=String.valueOf(url.hashCode());
            File f=new File(cacheDir, filename);
     
            //from SD cache
            Bitmap b = decodeFile(f);
            if(b!=null)
                return b;
     
            //from web
            try {
                Bitmap bitmap=null;
                InputStream is=new URL(url).openStream();
                OutputStream os = new FileOutputStream(f);
                Utils.CopyStream(is, os);
                os.close();
                bitmap = decodeFile(f);
                return bitmap;
            } catch (Exception ex){
               ex.printStackTrace();
               return null;
            }
        }
     
        //decodes image and scales it to reduce memory consumption
        private Bitmap decodeFile(File f){
            try {
                //decode image size
                BitmapFactory.Options o = new BitmapFactory.Options();
                o.inJustDecodeBounds = true;
                BitmapFactory.decodeStream(new FileInputStream(f),null,o);
     
                //Find the correct scale value. It should be the power of 2.
                final int REQUIRED_SIZE=70;
                int width_tmp=o.outWidth, height_tmp=o.outHeight;
                int scale=1;
                while(true){
                    if(width_tmp/2<REQUIRED_SIZE || height_tmp/2<REQUIRED_SIZE)
                        break;
                    width_tmp/=2;
                    height_tmp/=2;
                    scale++;
                }
     
                //decode with inSampleSize
                BitmapFactory.Options o2 = new BitmapFactory.Options();
                o2.inSampleSize=scale;
                return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
            } catch (FileNotFoundException e) {}
            return null;
        }
     
        //Task for the queue
        private class PhotoToLoad
        {
            public String url;
            public ImageView imageView;
            public PhotoToLoad(String u, ImageView i){
                url=u; 
                imageView=i;
            }
        }
     
        PhotosQueue photosQueue=new PhotosQueue();
     
        public void stopThread()
        {
            photoLoaderThread.interrupt();
        }
     
        //stores list of photos to download
        class PhotosQueue
        {
            private Stack<PhotoToLoad> photosToLoad=new Stack<PhotoToLoad>();
     
            //removes all instances of this ImageView
            public void Clean(ImageView image)
            {
                for(int j=0 ;j<photosToLoad.size();){
                    if(photosToLoad.get(j).imageView==image)
                        photosToLoad.remove(j);
                    else
                        ++j;
                }
            }
        }
     
        class PhotosLoader extends Thread {
            public void run() {
                try {
                    while(true)
                    {
                        //thread waits until there are any images to load in the queue
                        if(photosQueue.photosToLoad.size()==0)
                            synchronized(photosQueue.photosToLoad){
                                photosQueue.photosToLoad.wait();
                            }
                        if(photosQueue.photosToLoad.size()!=0)
                        {
                            PhotoToLoad photoToLoad;
                            synchronized(photosQueue.photosToLoad){
                                photoToLoad=photosQueue.photosToLoad.pop();
                            }
                            Bitmap bmp=getBitmap(photoToLoad.url);
                            cache.put(photoToLoad.url, bmp);
                                BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView);
                                Activity a=(Activity)photoToLoad.imageView.getContext();
                                a.runOnUiThread(bd);
                        }
                        if(Thread.interrupted())
                            break;
                    }
                } catch (InterruptedException e) {
                    //allow thread to exit
                }
            }
        }
     
        PhotosLoader photoLoaderThread=new PhotosLoader();
     
        //Used to display bitmap in the UI thread
        class BitmapDisplayer implements Runnable
        {
            Bitmap bitmap;
            ImageView imageView;
            public BitmapDisplayer(Bitmap b, ImageView i){bitmap=b;imageView=i;}
            public void run()
            {
                if(bitmap!=null)
                    imageView.setImageBitmap(bitmap);
                else
                    imageView.setImageResource(stub_id);
            }
        }
     
        public void clearCache() {
            //clear memory cache
            cache.clear();
     
            //clear SD cache
            File[] files=cacheDir.listFiles();
            for(File f:files)
                f.delete();
        }
     
     
     // Retourne la taille du Cache
        public String GetSizeOfDirectory()
        {
        	return formatSize(getFolderSize(cacheDir));
        }
     
     
     // Retourne la taille du dossier en Bytes
     	private static long getFolderSize(File dir) {
     	    long size = 0;
     	    for (File file : dir.listFiles()) {
     	        if (file.isFile()) {
     	            System.out.println(file.getName() + " " + file.length());
     	            size += file.length();
     	        }
     	        else
     	            size += getFolderSize(file);
     	    }
     	    return size;
     	}
     
     
     	private static String formatSize(long size) {
     		String suffix = null;
     
     		if(size == 0)
     		suffix = " KiB";
     
     		if (size >= 1024 && size != 0) {
     			suffix = " KiB";
     			size /= 1024;
     			if (size >= 1024) {
     				suffix = " MiB";
     				size /= 1024;
     			}
     		}
     		StringBuilder resultBuffer = new StringBuilder(Long.toString(size));
     
     		int commaOffset = resultBuffer.length() - 3;
     		while (commaOffset > 0) {
     			resultBuffer.insert(commaOffset, ',');
     			commaOffset -= 3;
     		}
     
     		if (suffix != null)
     			resultBuffer.append(suffix);
     		return resultBuffer.toString();
     	}
     
    }

  2. #2
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    Peut être le temps que le "loader" ne réponde...
    Il faudrait mettre la miniature à une image temporaire ("loading...") dans le getView histoire de pouvoir "effacer" l'ancienne image, le temps que loader ne donne la bonne....

    Ou alors, laisser cette opération au loader lui-meme:

    * Je regarde dans ma cache...
    .. * J'ai l'image ? Je l'utilise.
    .. * J'ai pas l'image ? Je met une image "loading..." et je queue la requete

    (EDIT)
    Merde, j'avais pas vu... c'est ce qui est fait:
    imageView.setBackgroundResource(R.drawable.draw_imageloading);

    Sauf que là c'est le background qui est mis, pas l'image elle-même (qui ne sera donc pas effacée si existante).
    setImageResource() devrait fonctionner
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  3. #3
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 281
    Points : 161
    Points
    161
    Par défaut
    Serait il possible que je mettre un progressDialog à la place de mon image temporaire ? Si oui comment ?

  4. #4
    Expert éminent

    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2007
    Messages
    4 253
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Février 2007
    Messages : 4 253
    Points : 7 618
    Points
    7 618
    Billets dans le blog
    3
    Par défaut
    il faudrait alors deux views... une view "ProgressBar" indeterminée... et une "ImageView"... cacher l'une quand l'autre est visible...
    N'oubliez pas de cliquer sur mais aussi sur si un commentaire vous a été utile !
    Et surtout

  5. #5
    Membre habitué
    Homme Profil pro
    Inscrit en
    Octobre 2011
    Messages
    281
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Octobre 2011
    Messages : 281
    Points : 161
    Points
    161
    Par défaut
    Voilà mon xml de chaque item de la ListView ci dessous.

    Que dois-je rajouter dans ces conditions ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    if(cache.containsKey(url))
            {
     
                imageView.setImageBitmap(cache.get(url));
     
            }
            else
            {
                  queuePhoto(url, activity, imageView);
                  imageView.setImageResource(R.drawable.loading);
     
     
     
            }

    Mon xml
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
     
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:background="@drawable/draw_item_actualite"
        android:orientation="horizontal"
        android:padding="15dp" >
     
      <ProgressBar
                    android:id="@+id/progressBar"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:indeterminate="true"
                    android:indeterminateDrawable="@drawable/costum_progress_bar" />
     
        <ImageView
            android:id="@+id/miniature"
            android:layout_width="0dp"
            android:layout_height="100dp"
            android:layout_marginRight="15dp"
            android:layout_weight="3.5"
            android:background="#2b2a2b" />
     
        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="6.5"
            android:orientation="vertical"
            android:paddingLeft="5dp" >
     
     
            <TextView
                android:id="@+id/titre"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:maxLines="2"
                android:lineSpacingExtra="4sp"
                android:singleLine="false"
                android:textStyle="bold"
                android:paddingBottom="10dp"
                android:textColor="#f60868"
                android:textSize="14sp" />
     
     
            <TextView
                android:id="@+id/extrait"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:ellipsize="end"
                android:lineSpacingExtra="4sp"
                android:maxLines="2"
                android:singleLine="false"
                android:textColor="#ffffff"
                android:textSize="12sp" />
        </LinearLayout>
     
    </LinearLayout>

Discussions similaires

  1. [FPDF] problème avec les images dans un tableau dynamique
    Par GADSN dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 08/04/2009, 11h11
  2. [IE] Problème avec background-image dans un TR?!
    Par Danny Blue dans le forum Mise en page CSS
    Réponses: 6
    Dernier message: 05/12/2007, 17h29
  3. Image dans listview mode détail
    Par metallica14 dans le forum VB.NET
    Réponses: 1
    Dernier message: 26/07/2007, 13h23
  4. Problème de superposition d'images dans Movie
    Par pouette13 dans le forum MATLAB
    Réponses: 2
    Dernier message: 22/07/2007, 19h17
  5. [vb2005] Images dans Listview
    Par stargates dans le forum Windows Forms
    Réponses: 4
    Dernier message: 07/08/2006, 15h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo