Загрузка Lazyload связывает изображения с неправильным представлением в множественном просмотре списка в том же действии - PullRequest
0 голосов
/ 01 февраля 2012

Я использую ленивый класс загрузки Imageloader для получения изображений с веб-сервера, у меня около 3 списков в одном и том же упражнении, по какой-то причине одно из этих списков связывает изображения неверным образом. Я хочу загрузить свое действие и начать загрузка изображений для каждого списка. Есть ли эффективный способ для этого? Lazyload раньше работал ... как я могу указать каждый вид на каждое изображение должно быть загружено? любая помощь будет оценена :) </p> <pre><code>public class ImageLoader { private HashMap<String, Bitmap> cache=new HashMap<String, Bitmap>(); private RotateAnimation rotate=null; private String MainDirectory=".Beirut.com"; private String Directory=".images"; private File cacheDir; public ImageLoader(Context context){ //Make the background thread low priority. This way it will not affect the UI performance photoLoaderThread.setPriority(Thread.NORM_PRIORITY-1); //checking if the main Directory exist? if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) cacheDir=new File(android.os.Environment.getExternalStorageDirectory(),MainDirectory); else cacheDir=context.getCacheDir(); if(!cacheDir.exists()) cacheDir.mkdirs(); //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(),MainDirectory+"/"+Directory); else cacheDir=context.getCacheDir(); if(!cacheDir.exists()) cacheDir.mkdirs(); } final int stub_id=R.drawable.refresh_resized_silver; public void DisplayImage(String url, Activity activity, ImageView imageView) { //Log.e("Image to load",url); rotate=new RotateAnimation(0f, 360f, Animation.RELATIVE_TO_SELF,0.5f, Animation.RELATIVE_TO_SELF,0.5f); rotate.setDuration(1000L); rotate.setRepeatMode(Animation.INFINITE); rotate.setRepeatCount(Animation.INFINITE); imageView.setImageResource(stub_id); imageView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); //imageView.setBackgroundResource(stub_id); imageView.startAnimation(rotate); if(cache.containsKey(url)){ imageView.setImageBitmap(cache.get(url)); imageView.invalidate(); imageView.setScaleType(ScaleType.CENTER_INSIDE); imageView.clearAnimation(); //Log.e("Animation","Cleared"); } else { queuePhoto(url, activity, imageView); } } 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(); } public static Bitmap loadImageFromUrl(String url) { InputStream inputStream; Bitmap b; try { if(url.contains(" ")){ url=url.replace(" ", "%20"); } //Log.e("Error link",url); inputStream = (InputStream) new URL(url).getContent(); BitmapFactory.Options bpo= new BitmapFactory.Options(); bpo.inJustDecodeBounds = true; bpo.inJustDecodeBounds = false; if(bpo.outWidth>400){ bpo.inSampleSize = 1; b=BitmapFactory.decodeStream(inputStream, null,bpo ); }else{ bpo.inSampleSize=1; b=BitmapFactory.decodeStream(inputStream, null,bpo ); } return b; }catch (IOException e) { throw new RuntimeException(e); } } 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); //bitmap=loadImageFromUrl(url); 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=300; 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*=2; } //decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize=scale; try{ return BitmapFactory.decodeStream(new FileInputStream(f), null, o2); }catch(FileNotFoundException e){ return null; } } 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); Object tag=photoToLoad.imageView.getTag(); if(tag!=null && ((String)tag).equals(photoToLoad.url)){ BitmapDisplayer bd=new BitmapDisplayer(bmp, photoToLoad.imageView); Activity a=(Activity)photoToLoad.imageView.getContext(); a.runOnUiThread(bd); } } if(Thread.interrupted()) break; } } catch (InterruptedException e) { } } } PhotosLoader photoLoaderThread=new PhotosLoader(); 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); BitmapDrawable drawable = (BitmapDrawable) imageView.getDrawable(); drawable.setAntiAlias(true); imageView.setScaleType(ScaleType.CENTER_INSIDE); imageView.clearAnimation(); //Log.e("Animation","Cleared"); } } public void clearCache() { cache.clear(); //clear SD cache File[] files=cacheDir.listFiles(); for(File f:files) f.delete(); } }

и метод getview следующим образом:

</p> <pre><code>public View getView(int position, View convertView, ViewGroup parent) { View vi=convertView; ViewHolder holder; if(convertView==null){ vi = inflater.inflate(R.layout.videoitem, null); holder=new ViewHolder(); holder.text=(TextView)vi.findViewById(R.id.text); holder.image=(ImageView)vi.findViewById(R.id.image); holder.typetext=(TextView)vi.findViewById(R.id.typetext); holder.description=(TextView)vi.findViewById(R.id.description); vi.setTag(holder); }else{ holder=(ViewHolder)vi.getTag(); } String dprow=""; //data comes from search list if(!data.get(position).getTitle().trim().equalsIgnoreCase("")){ dprow+="<b><strike>"+data.get(position).getTitle().trim()+"</strike></b>"+"<br>"; } String urltoload="http://img.youtube.com/vi/"+data.get(position).getYoutube()+"/0.jpg"; if(urltoload.contains(" ")){ urltoload=urltoload.replace(" ", "%20"); } holder.text.setText(Html.fromHtml(dprow)); holder.image.setTag(urltoload); holder.typetext.setText(data.get(position).getType()); holder.description.setText(urltoload); imageLoader.DisplayImage(urltoload, activity, holder.image); return vi; }

Я использовал notifyDataSetChanged () для обновления представлений, но это делает его таким медленным. Есть ли лучший способ загрузить изображения в фоновом режиме для каждого вида отдельно

1 Ответ

0 голосов
/ 01 февраля 2012

Используйте 3 diffrent image_loader (объект ленивого загрузчика), чтобы загрузить изображение для каждого класса.Поскольку ленивый список проверяет старый запрос и вид, если он существует, отмените его и добавьте запрос нового изображения.

...