web-dev-qa-db-fra.com

Mise en cache des images et affichage

Bonjour Je suis confronté à un problème particulier dans lequel je dois télécharger des images et les afficher sur une ListView correspondant à leur TextView's particulier. Le code que j'ai est en train d’afficher avec succès le TextView's que j’ai besoin d’afficher, mais je ne sais pas comment afficher toutes ces images à côté de mes vues de texte dans ma ListView.

Après avoir traversé de nombreuses discussions dans SO. Les réponses les plus fréquentes sont de résoudre ce problème en 1. Liste paresseuse 2. Chargeur d'image universel

J'ai passé en revue les deux solutions. J'ai téléchargé des codes Lazy List dans lesquels les URL sont des chaînes codées en dur stockées dans un tableau. Ce que je voudrais faire, c'est créer mes propres chaînes de manière dynamique. Stockez-les dans la mémoire cache et affichez toutes les images correspondantes.

Voici mon code:

public class Tools_ListItemActivity extends ListActivity 
{
    private Context context;
    String s;

    private static final String TAG_POSTS = "posts";
    private static final String TAG_MDNAME = "mdname";
    private static final String TAG_UTCOST = "utcost";
    private static final String TAG_IIMG= "iimg";
    JSONArray posts = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);
        s=getIntent().getExtras().getString("url");
        new ProgressTask(Tools_ListItemActivity.this).execute();
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        // TODO Auto-generated method stub
        super.onListItemClick(l, v, position, id);
    }

ArrayList<HashMap<String, String>> jsonlist = new ArrayList<HashMap<String, String>>();

     ListView lv ;



      private class ProgressTask extends AsyncTask<String, Void, Boolean> {
      private ProgressDialog dialog;

       public ProgressTask(ListActivity activity) {

       Log.i("1", "Called");
       context = activity;
       dialog = new ProgressDialog(context);
      }

       /** progress dialog to show user that the backup is processing. */

       /** application context. */
      private Context context;

       protected void onPreExecute() {
       this.dialog.setMessage("Progress start");
       this.dialog.show();
      }

       @Override
      protected void onPostExecute(final Boolean success) {
       if (dialog.isShowing()) {
        dialog.dismiss();
       }
       ListAdapter adapter = new SimpleAdapter(context, jsonlist,
         R.layout.activity_toolsitem, new String[] { TAG_IIMG, TAG_MDNAME, TAG_UTCOST  }, new int[] {
           R.id.imageViewUrl, R.id.mdname, R.id.utcost });

        setListAdapter(adapter);

        // selecting single ListView item
        lv = getListView();

      }

       protected Boolean doInBackground(final String... args) {

        JSONParser jParser = new JSONParser();

        // getting JSON string from URL
        JSONObject json = jParser.getJSONFromUrl(s);


        try {
            posts = json.getJSONArray(TAG_POSTS);
        } catch (JSONException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        try
        {
        // looping through All Contacts
        for(int i = 0; i < posts.length(); i++){
            JSONObject c = posts.getJSONObject(i);

            // Storing each json item in variable
            String mdname = c.getString(TAG_MDNAME);
            String utcost= c.getString(TAG_UTCOST);
            String iimg=c.getString(TAG_IIMG);

            //Forming the Url of the image to be shown in the list view
            String imageUrl="My_App_URL"+iimg;

/*  try {

              String imageUrl="My_App_URL"+iimg;
              ImageView imageView = (ImageView)findViewById(R.id.imageViewUrl);
              Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
              imageView.setImageBitmap(bitmap); 
            } catch (MalformedURLException e) {
              e.printStackTrace();
            } catch (IOException e) {
              e.printStackTrace();
            } */


            // creating new HashMap
            HashMap<String, String> map = new HashMap<String, String>();

            // adding each child node to HashMap key => value
            map.put(TAG_MDNAME, mdname);
            map.put(TAG_UTCOST, utcost);
            map.put(TAG_IIMG, iimg);



         jsonlist.add(map);
        } }catch (JSONException e) 
        {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }


        return null;


       }

      }





}

Ici, j'ai débogué et découvert que imageUrl est formé correctement. Json renvoie uniquement le nom de la jpg, donc je l’ajoute à l’URL et je l’enregistre dans imageUrl. Les deux autres vues textuelles sont correctement analysées et affichées. Si quelqu'un peut m'aider à afficher les images dans la vue d'image aussi, ce serait formidable. Merci. 

Mise à jour: J'ai pu résoudre mon problème particulier avec l'aide du lien partagé par Pankaj ( https://github.com/AndroidBegin/Android-JSON-Parse-Images-and-Texts -Tutorial ) et la connaissance conceptuelle partagée par Raghunandan ci-dessous. Veuillez parcourir ces réponses pour une explication détaillée ainsi que la mise en œuvre du chargement paresseux. Je m'excuse de ne pas pouvoir récompenser une réponse par une prime, car j'étais absent pendant deux jours.

16
D'yer Mak'er

Chargement paresseux avec Universal Imageloader. Remplacez les URL codées en dur par des URL d’images.

Modifiez le ci-dessous en fonction de vos besoins

Qu'est-ce que LazyList? . Vérifiez ce lien pour plus de détails.

MainActivity.Java

public class MainActivity extends Activity {

  private String[] mStrings={
            "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-Twitter.png",
            "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/Android_logo_normal.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_Android_normal.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet.png",
            "http://a3.twimg.com/profile_images/670625317/aam-logo-v3-Twitter_normal.png",
            "http://a3.twimg.com/profile_images/740897825/AndroidCast-350_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf_normal.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/768060227/ap4u_normal.jpg",
            "http://a1.twimg.com/profile_images/74724754/Android_logo.png",
            "http://a3.twimg.com/profile_images/681537837/SmallAvatarx150_normal.png",
            "http://a1.twimg.com/profile_images/63737974/2008-11-06_1637_normal.png",
            "http://a3.twimg.com/profile_images/548410609/icon_8_73_normal.png",
            "http://a1.twimg.com/profile_images/612232882/nexusoneavatar_normal.jpg",
            "http://a1.twimg.com/profile_images/213722080/Bugdroid-phone_normal.png",
            "http://a1.twimg.com/profile_images/645523828/OT_icon_090918_Android.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small_normal.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto_normal.jpg",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png",
            "http://a1.twimg.com/profile_images/605536070/twitterProfilePhoto.jpg",
            "http://a1.twimg.com/profile_images/850960042/elandroidelibre-logo_300x300_normal.jpg",
            "http://a1.twimg.com/profile_images/655119538/andbook_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/121630227/Droid_normal.jpg",
            "http://a1.twimg.com/profile_images/957149154/twitterhalf.jpg",
            "http://a1.twimg.com/profile_images/97470808/icon_normal.png",
            "http://a3.twimg.com/profile_images/511790713/AG_normal.png",
            "http://a3.twimg.com/profile_images/956404323/androinica-avatar_normal.png",
            "http://a1.twimg.com/profile_images/909231146/Android_Biz_Man_normal.png",
            "http://a3.twimg.com/profile_images/72774055/AndroidHomme-LOGO_normal.jpg",
            "http://a1.twimg.com/profile_images/349012784/Android_logo_small.jpg",
            "http://a1.twimg.com/profile_images/841338368/ea-Twitter-icon_normal.png",
            "http://a3.twimg.com/profile_images/64827025/Android-wallpaper6_2560x160_normal.png",
            "http://a3.twimg.com/profile_images/77641093/AndroidPlanet_normal.png"
    };

    ListView lv;    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv= (ListView) findViewById(R.id.lv);
        lv.setAdapter(new LazyAdapter(this,mStrings));
    }
}

activity_main.xml

<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:paddingBottom="@dimen/activity_vertical_margin"
    Android:paddingLeft="@dimen/activity_horizontal_margin"
    Android:paddingRight="@dimen/activity_horizontal_margin"
    Android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >
    <ListView
        Android:id="@+id/lv"
        Android:layout_width="fill_parent"
        Android:layout_height="fill_parent"
        Android:background="#000000"
        Android:focusableInTouchMode="false"
        Android:listSelector="@Android:color/transparent"
        Android:layout_weight="2.0"
        Android:divider="#000000"
        Android:headerDividersEnabled="false"
        Android:footerDividersEnabled="false"
        Android:dividerHeight="8dp"
        Android:drawSelectorOnTop="false"
        />
</RelativeLayout>

LazyAdapter.Java

public class LazyAdapter extends BaseAdapter {
    private Activity activity;
    private String data[];
    private LayoutInflater inflater=null;
    public ImageLoader imageLoader; 
    DisplayImageOptions options;
    public LazyAdapter(Activity a, String[] d) {
        activity = a;
        data=d;
        inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        File cacheDir = StorageUtils.getOwnCacheDirectory(a, "MyFolderCache");

        // Get singletone instance of ImageLoader
        imageLoader = ImageLoader.getInstance();
        // Create configuration for ImageLoader (all options are optional)
        ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(a)
              // You can pass your own memory cache implementation
             .discCacheExtraOptions(1024, 1024, CompressFormat.PNG, 100)
             .discCache(new UnlimitedDiscCache(cacheDir)) // You can pass your own disc cache implementation
             .discCacheFileNameGenerator(new HashCodeFileNameGenerator())
             .enableLogging()
             .build();
        // Initialize ImageLoader with created configuration. Do it once.
        imageLoader.init(config);
        //imageLoader.init(ImageLoaderConfiguration.createDefault(a));
        // imageLoader=new ImageLoader(activity.getApplicationContext());
        options = new DisplayImageOptions.Builder()
             .showStubImage(R.drawable.ic_launcher)
             .cacheInMemory()
             .cacheOnDisc()
             .displayer(new RoundedBitmapDisplayer(20))
             .build();
    }

    public int getCount() {
        return data.length;
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        View vi=convertView;
        ViewHolder vh = new ViewHolder();;
        if(convertView==null)
        {

            vi = inflater.inflate(R.layout.row, null);   
            vh.iv=(ImageView)vi.findViewById(R.id.ivv); 
            vh.pb= (ProgressBar)vi.findViewById(R.id.pb); 
            vh.tv = (TextView) vi.findViewById(R.id.textView1);
            vh.tv1= (TextView) vi.findViewById(R.id.textView2);
        }
        vh.tv.setText("Image in postion =");
        vh.tv1.setText(""+position);
        display(vh.iv, data[position], vh.pb);
        //imageLoader.displayImage(data.get(position).toString(), image,options);
        return vi;
    }

    public void display(ImageView img, String url, final ProgressBar spinner)
    {
        imageLoader.displayImage(url, img, options, new ImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                spinner.setVisibility(View.VISIBLE);
            }
            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                spinner.setVisibility(View.GONE);
            }
            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
            spinner.setVisibility(View.GONE);
            }
            @Override
            public void onLoadingCancelled(String imageUri, View view) {

            }
        });
    }

    public static class ViewHolder
    {
        ImageView iv;
        TextView tv,tv1;
        ProgressBar pb;
    }
}

row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:orientation="vertical" >
    <ImageView
        Android:id="@+id/imageView1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_centerHorizontal="true"
        Android:layout_centerVertical="true"
        Android:src="@drawable/ic_launcher" />
    <ProgressBar 
        Android:id="@+id/pb"
        Android:layout_centerInParent="true"
        Android:layout_gravity="center"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"/>
    <TextView
        Android:id="@+id/textView1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_above="@+id/textView2"
        Android:layout_alignParentLeft="true"
        Android:layout_marginBottom="21dp"
        Android:layout_marginLeft="31dp"
        Android:text="TextView" />
    <TextView
        Android:id="@+id/textView2"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_alignLeft="@+id/textView1"
        Android:layout_alignParentBottom="true"
        Android:text="TextView" />
</RelativeLayout>

Ajouter une autorisation dans le manifeste

 <uses-permission Android:name="Android.permission.INTERNET"/>

enter image description here

17
Raghunandan

Essayez ceci avec le chargeur d'images universel

public class DetailsListViewAdapter extends ArrayAdapter<Entry>{
    private Context context;
    private List<Entry> detailList;
    DisplayImageOptions options;
    public ImageLoader imageLoader;

    public DetailsListViewAdapter(Context context, int textViewResourceId,List<Entry> detailList) {
        super(context, textViewResourceId,detailList);
        this.detailList = detailList;
        this.context = context;
        imageLoader = ImageLoader.getInstance();
        imageLoader.init(ImageLoaderConfiguration.createDefault(context));
        options = new DisplayImageOptions.Builder()
        .showImageForEmptyUri(R.drawable.blankimage)
        .showImageOnFail(R.drawable.blankimage)
        .resetViewBeforeLoading()
        .cacheOnDisc()
        .imageScaleType(ImageScaleType.IN_SAMPLE_INT)
        .bitmapConfig(Bitmap.Config.RGB_565)
        .displayer(new FadeInBitmapDisplayer(300))
        .build();
    }

    static class ViewHolder{
        private TextView popupDetails;
        private TextView pubDate;
        private ImageView image;
        private ProgressBar progress;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ViewHolder holder;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.details_list_item, null);
            holder = new ViewHolder();
            holder.popupDetails=(TextView)v.findViewById(R.id.detailHeading);
            holder.pubDate = (TextView)v.findViewById(R.id.pubDate);
            holder.image = (ImageView)v.findViewById(R.id.listImg);
            holder.progress = (ProgressBar)v.findViewById(R.id.progressBar);
            v.setTag(holder);
        } else {
            holder = (ViewHolder) v.getTag();
        }
        Entry value = detailList.get(position);
        holder.popupDetails.setText(value.getTitle());
        holder.pubDate.setText(value.getPubDate());
        String url = value.getImageLink();
        try {
            if(url.length() > 5) {
                holder.image.setVisibility(View.VISIBLE);
                loadImage(holder.image,url,holder.progress);
            } else {
                if(url.equals("NO")) {
                    holder.image.setVisibility(View.INVISIBLE);
                } else {
                    holder.image.setVisibility(View.GONE);
                }
            }
        } catch (Exception e) {
            Logger.show(e);
        }
        v.setBackgroundColor(Color.WHITE);
        return v;

    }
    public void loadImage(ImageView imageView, String loadURL,final ProgressBar progress) {
        imageLoader.displayImage(loadURL, imageView, options, new SimpleImageLoadingListener() {
            @Override
            public void onLoadingStarted(String imageUri, View view) {
                progress.setVisibility(View.VISIBLE);
            }

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
                String message = null;
                switch (failReason) {
                case IO_ERROR:
                    message = "Input/Output error";
                    break;
                case OUT_OF_MEMORY:
                    message = "Out Of Memory error";
                    break;
                case NETWORK_DENIED:
                    message = "Downloads are denied";
                    break;
                case UNSUPPORTED_URI_SCHEME:
                    message = "Unsupported URI scheme";
                    break;
                case UNKNOWN:
                    message = "Unknown error";
                    break;
                }
                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onLoadingComplete(final String imageUri, View view, final Bitmap loadedImage) {
                progress.setVisibility(View.INVISIBLE);
            }  
        });
    }
}
3
OMAK

Voici comment je charge et met en cache des images dans une ListView qui crée une liste de contacts pour l'utilisateur. Alors imaginez une image de profil sur la gauche, quelques vues de texte sur la droite (ce qui semble proche du problème que vous rencontrez. Ignorez les tags de débogage laids et probablement un formatage médiocre (désolé). Je suppose que cela ressemble à LazyList mais une explication détaillée au cas où quelqu'un serait confus. 

Étape 1: Configurez votre cache

private LruCache<String, Bitmap> memoryCache;
private HashMap<String, String> idPairs = new HashMap<String, String>(); 

Dans mon approche, j'utilise une LruCache et une HashMap pour suivre les images d'utilisateur que j'ai téléchargées. Vous verrez comment sa mise en œuvre plus tard, mais l'idée est d'éviter de télécharger des choses à partir du serveur sauf si vous devez le faire. Ensuite, dans votre onCreate() ou une méthode associée, initialisez votre cache.

    final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
    final int cacheSize = maxMemory / 8;
    memoryCache = new LruCache<String, Bitmap>(cacheSize)  {
        @Override 
        protected int sizeOf(String key, Bitmap bitmap){
            return (bitmap.getRowBytes() * bitmap.getHeight()) / 1024; //don't use getByteCount for API < 12
        }
    };

Ma prochaine étape consiste à ajouter le bitmap "image vide" par défaut au cache au cas où j'aurais atteint une entrée sans image associée. De cette façon, je n'ai qu'à traiter et ajouter ce bitmap une fois

Bitmap defaultPicture = BitmapFactory.decodeResource(getResources(), R.drawable.default_user_picture);
    addBitmapToMemoryCache("default", defaultPicture);

Ensuite, il est temps d'obtenir les données dont vous avez besoin pour la liste!

Étape 2: Récupérer les données

private class GetPeopleData extends AsyncTask<JSONArray, Void, Void> {

    @Override
    protected Void doInBackground(JSONArray...lists) {
        HttpClient httpClient = new DefaultHttpClient(); 
        HttpPost httpPost = new HttpPost();
        ResponseHandler <String> responseHandler = new BasicResponseHandler();
        if(DEBUG) Log.d("GET PEOPLE DATA TASK", lists[0].length() + " users");
        getUsers(lists[0], httpClient, httpPost, responseHandler);
        return null;
    }

    @Override
    protected void onPostExecute(Void result){
        updateUserListView();
    }

}

Voici une variable AsyncTask qui prend comme argument une JSONArray de données utilisateur. J'ai omis cette partie car il ne s'agit en fait que d'un téléchargement HTTP de base qui n'a pas besoin d'explication. La méthode getUsers est l'endroit où je commence à rassembler ce qui sera ajouté à ma ListView. Ce que je fais ensuite est de traiter le fichier JSON téléchargé à partir du serveur pour créer des objets utilisateur qui seront ajoutés à la liste des utilisateurs à afficher. 

private void getUsers(JSONArray userArray, HttpClient httpClient, HttpPost httpPost, ResponseHandler<String> responseHandler){
    if(DEBUG) Log.d("USERS ARRAY", userArray.length() + " users");
    try{

        users = new ArrayList<User>();
        if(DEBUG) Log.d("User Array -START", "" + users.size());
        //Go through userArray and get information needed for list
        for(int i = 0; i < userArray.length(); i++){
            User u = new User();
            if(DEBUG) Log.d("User Array - ADD USER", "" + users.size());
            String profileId = userArray.getJSONObject(i).getString("profileid");
            u.setId(userArray.getJSONObject(i).getString("id"));
            u.setDisplayName(userArray.getJSONObject(i).getString("displayname"));
            u.setStatus(userArray.getJSONObject(i).getString("status"));

            //check HashMap for sender/profileid pair
            if(idPairs.containsKey(profileId)){
                if(DEBUG) Log.d("idPairs", "User in HashMap");
                profileId = idPairs.get(profileId);
            } else {
                if(DEBUG) Log.d("idPairs", "User not in HashMap. Add profileId");
                idPairs.put("profileId", profileId);
            }
            u.setProfilePicture(getProfilePictureFromCache(profileId, httpClient, httpPost, responseHandler)); //check cache for image
            users.add(u);
            if(DEBUG) Log.d("User info", u.toString());
        }
    } catch (Exception e) {
        Log.e("BACKGROUND_PROC", e.getMessage());
    }
}

J'associe l'image à l'objet utilisateur qui sera éventuellement affiché. Je suppose que ce n'est pas une perte de temps totale puisque l'image est extraite du cache bitmap

private Bitmap getProfilePictureFromCache(String profileId, HttpClient httpClient, HttpPost httpPost, ResponseHandler<String> responseHandler){
    Bitmap defaultPicture = getBitmapFromMemCache("default");
    Bitmap profilePicture = getBitmapFromMemCache(profileId);
    if(profilePicture != null){
        return profilePicture;
    } else {        
        String pictureString = getProfilePic(profileId, httpClient, httpPost, responseHandler);
        if(!pictureString.isEmpty()){       
            byte[] decodedString = Base64.decode(pictureString, Base64.DEFAULT);
            profilePicture = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
            addBitmapToMemoryCache(profileId, profilePicture);
            if(DEBUG) Log.d("MEMCACHE", "Download and store picture for " + profileId);
            return profilePicture;
        } else if (defaultPicture != null && pictureString.equals(null)) {
            if(DEBUG) Log.d("MEMCACHE", "Load default picture");
            return defaultPicture;
        }
    }
    return defaultPicture;
}

Si une image existe dans le cache, elle est renvoyée, sinon elle est téléchargée. Pour moi, lors de l'affichage des utilisateurs, chaque image est mise en cache en fonction de l'ID utilisateur. Même si une personne devait apparaître plusieurs fois dans la liste, une seule image serait stockée dans le cache pour cet utilisateur. 

ImageView profile_picture = (ImageView) v.findViewById(R.id.profile_picture);
if(profile_picture != null){
                profile_picture.setImageBitmap(u.getProfilePicture());
            }

La seule chose qui reste à faire est de trouver la ImageView dans votre adaptateur et de définir cette vue sur l'image que vous avez associée à l'objet dans votre liste. 

2
Rarw

Voulez-vous quelque chose de facile à utiliser? Avec s'occuper de la mise en cache des fichiers, la suppression du cache, libérer lorsque la mémoire est à la frontière?

Essayez LazyList, allez y:

https://github.com/nicolasjafelle/LazyList

Comme il est expliqué, il vous suffit de créer le Singleton dans votre classe Application ou dans toute autre activité ou fragment:

//To use the default external folder, this folder will be deleted when the app no longe exists.
ImageLoader.getInstance().init(getApplicationContext());
//Or to use another folder, use...
//ImageLoader.getInstance().init(getApplicationContext(), "MyExternalFolder");

Ensuite, dans votre vue qui contient ImageView pour afficher l'image, vous devez implémenter l'interface ImageProcessingCallback:

public class MyItemView extends LinearLayout implements ImageProcessingCallback {
...
//Do what you need in methods onImagePreProcessing() and onImageProcessing(Bitmap     bitmap)
...
ImageLoader.getInstance().displayImage(data[position], myView);

Enfin, vous devez ajouter cette autorisation dans votre androidManifest.xml

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

Et c'est tout. Vous disposez ensuite de méthodes pour effacer le cache pour le cache ram ou le cache de disque, ou les deux.

1
Nicolas Jafelle

Je ne sais pas comment stocker les images, car mon application utilise des images de l'APK . Cependant, je crois que pour afficher ces images, vous souhaitez un Arrayadapter personnalisé.

Cela gonfle une mise en page pour chaque élément et le place dans une liste. Cette disposition est définie par une disposition XML que vous créez et spécifiez dans sa construction. Vous devriez essayer d'étendre l'adaptateur que vous utilisez actuellement pour votre affichage sous forme de liste avec un adaptateur personnalisé qui définit l'affichage d'image en fonction de l'élément.

Je le fais avec ImageView.setImageResource (ID de ressource); Mais votre kilométrage peut varier. J'ai mes images dans l'APK pas sûr de savoir comment les afficher à partir d'une source externe

0
TJC