2013-04-11 67 views
0

我与这个人有同样的问题 Listview shows wrong images如何在listview中缓存imageview?

我看到了我必须缓存它的解决方案。但在我的缓存中,我不确定如何应用解决方案中给出的缓存。我不断收到错误。

我怀疑这是我有问题的一部分:

holder.icon.setImageBitmap(bitmapList[position]); 

      //loadImageBitmap(mObjects.get(position), position); 

      //onBitmapLoaded(position, holder.mTask.myBitmap()); 

下面是代码。 Adapter.java 公共类适配器扩展BaseAdapter {

private static final String TAG = "Adapter"; 
    private Activity mActivity; 
    public ArrayList<Data> mObjects; 

    static class ViewHolder { 
     ImageView icon; 
     TextView title; 
     WebView newimage; 
     DownloadImageTask mTask; 
     public void setOnClickListener(OnItemClickListener onItemClickListener) { 
      // TODO Auto-generated method stub 

     } 
    } 



    private Bitmap[] bitmapList; 
    private Bitmap bitmapPlaceholder; 

    private void initBitmapListWithPlaceholders(){ 
    // call this whenever the list size changes 
    // you can also use a list or a map or whatever so you 
    // don't need to drop all the previously loaded bitmap whenever 
    // the list contents are modified 
     int count = getCount(); 
     bitmapList = new Bitmap[count]; 
     for(int i=0;i<count;i++){ 
      bitmapList[i]=bitmapPlaceholder; 
     } 
    } 

    private void onBitmapLoaded(int position, Bitmap bmp){ 
    // this is your callback when the load async is done 
     bitmapList[position] = bmp; 
    } 

    public Adapter(Activity activity, ArrayList<Data> mObjects) { 

     this.mActivity = (Activity) activity; 
     this.mObjects = mObjects; 


    } 

    public void setObjects(ArrayList<Data> mObjects) { 
     this.mObjects = mObjects; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     Data item = mObjects.get(position); 
     View rowView = convertView; 

     if (rowView == null) { 
      LayoutInflater inflater = mActivity.getLayoutInflater(); 
      rowView = inflater.inflate(R.layout.item, parent, false); 


      ViewHolder viewHolder = new ViewHolder(); 
      viewHolder.icon = (ImageView) rowView.findViewById(R.id.image); 
      viewHolder.title = (TextView) rowView.findViewById(R.id.title); 

      viewHolder.newimage =(WebView)rowView.findViewById(R.id.newimage); 


      rowView.setTag(viewHolder); 
     } 

     ViewHolder holder = (ViewHolder) rowView.getTag(); 

     holder.title.setText(item.getmTitle()); 

     //String html = " <html><head></head><body><p font-size='8px'>" + item.getmImageUrl() + "</p><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>"; 
     String html = " <html><head></head><body><img src='" + item.getmImageUrl() + "' width='100%' height='100%'></body></html>"; 




     holder.newimage.loadData(html, "text/html", "utf-8"); 

     holder.newimage.setFocusable(false); 
     holder.newimage.setClickable(false); 
     holder.setOnClickListener(new OnItemClickListener() { 

      private Object title; 

      public void onItemClick(AdapterView<?> parent, View v, int position, long id) { 
       //Toast.makeText(Adapter.this,"Button is clicked", Toast.LENGTH_LONG).show(); 
       Log.e("log_tag",this.title.toString() + " clicked"); 
      } 
     }); 

     //holder.icon.setBackgroundResource(R.drawable.ic_launcher); 
     holder.mTask = new DownloadImageTask(item.getmImageUrl(), holder.icon); 


     holder.icon.setImageBitmap(bitmapList[position]); 

     //loadImageBitmap(mObjects.get(position), position); 

     //onBitmapLoaded(position, holder.mTask.myBitmap()); 
     if (!holder.mTask.isCancelled()) { 
      holder.mTask.execute(); 
     } 


     return rowView; 
    } 

    @Override 
    public int getCount() { 

     return (this.mObjects.size()); 
    } 

    @Override 
    public Object getItem(int position) { 

     return (this.mObjects.get(position)); 
    } 

    @Override 
    public long getItemId(int position) { 

     return (position); 
    } 

    public AbsListView.RecyclerListener mRecyclerListener = new RecyclerListener(){ 

     public void onMovedToScrapHeap(View view) { 
      ViewHolder viewHolder = (ViewHolder) view.getTag(); 
      DownloadImageTask imagetask = viewHolder.mTask; 
      if (imagetask != null) { 
       imagetask.cancel(true); 
      } 
     } 

    }; 

    public void setOnClickListener(OnItemClickListener onItemClickListener) { 
     // TODO Auto-generated method stub 

    } 

DownloadImageTask.java

import java.io.FilterInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.widget.ImageView; 

public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { 
    public Bitmap g; 
    private String mUrl; 
    private ImageView mImageView = null; 

    public DownloadImageTask(String Url, ImageView imageView) { 

     mUrl = Url; 
     this.mImageView = imageView; 
    } 

    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 
     if (result != null) { 
      mImageView.setImageBitmap(result); 
      //result.recycle(); 
     } 
    } 

    protected Bitmap doInBackground(Void... params) { 

     Bitmap bitmap = getBitmap(mUrl); 
     return bitmap; 
    } 

    public Bitmap getBitmap(String imageUrl) { 
     Bitmap mBitmap = null; 
     try { 

      /*URL newurl = new URL(imageUrl); 
      mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */ 
      //mImageView.setImageBitmap(mBitmap); 

      /* 
      URL url = new URL(imageUrl); 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      InputStream is = conn.getInputStream(); 
      mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/ 


      InputStream in = new java.net.URL(imageUrl).openStream(); 
      mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in)); 
      //mBitmap.recycle(); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     this.g = mBitmap; 
     return mBitmap; 
    } 

    public Bitmap myBitmap() { 
     Bitmap fg; 
     fg = (Bitmap) g; 

     return fg; 
    } 

    static class FlushedInputStream extends FilterInputStream { 
     public FlushedInputStream(InputStream inputStream) { 
      super(inputStream); 
     } 

     @Override 
     public long skip(long n) throws IOException { 
      long totalBytesSkipped = 0L; 
      while (totalBytesSkipped < n) { 
       long bytesSkipped = in.skip(n - totalBytesSkipped); 
       if (bytesSkipped == 0L) { 
        int b = read(); 
        if (b < 0) { 
         break; // we reached EOF 
        } else { 
         bytesSkipped = 1; // we read one byte 
        } 
       } 
       totalBytesSkipped += bytesSkipped; 
      } 
      return totalBytesSkipped; 
     } 
    } 

} 

编辑

我已经修改DownloadImageTask.java按照此代码做一些缓存:https://stackoverflow.com/a/7730547

但我似乎有这方面的问题:

if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) { 
      /* The path is not same. This means that this 
       image view is handled by some other async task. 
       We don't do anything and return. */ 
      return; 
     } 

由于if ...行,应用程序总是崩溃。这让人非常沮丧。我需要帮助。请帮帮我。下面是修改后的DownloadImageTask.Java

import java.io.FilterInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.net.MalformedURLException; 

import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.os.AsyncTask; 
import android.view.View; 
import android.widget.ImageView; 

public class DownloadImageTask extends AsyncTask<Void, Void, Bitmap> { 
    public Bitmap g; 
    private String mUrl; 
    private ImageView mImageView = null; 

    public DownloadImageTask(String Url, ImageView imageView) { 


     mUrl = Url; 
     this.mImageView = imageView; 




    } 

    protected void onPostExecute(Bitmap result) { 
     super.onPostExecute(result); 

     /* 
     if (result != null) { 
      mImageView.setImageBitmap(result); 

     } 
     */ 
     if (!(this.mImageView.getTag().toString()).equals(this.mUrl)) { 
      /* The path is not same. This means that this 
       image view is handled by some other async task. 
       We don't do anything and return. */ 
      return; 
     } 

     if(result != null && mImageView != null){ 
      mImageView.setVisibility(View.VISIBLE); 
      mImageView.setImageBitmap(result); 
      mImageView.setTag(this.mUrl); 
     }else{ 
      mImageView.setVisibility(View.GONE); 
     } 


    } 

    protected Bitmap doInBackground(Void... params) { 

     Bitmap bitmap = getBitmap(mUrl); 
     return bitmap; 




    } 

    public Bitmap getBitmap(String imageUrl) { 


     Bitmap mBitmap = null; 
     try { 

      /*URL newurl = new URL(imageUrl); 
      mBitmap = BitmapFactory.decodeStream(newurl.openConnection() .getInputStream()); */ 
      //mImageView.setImageBitmap(mBitmap); 

      /* 
      URL url = new URL(imageUrl); 
      HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 
      InputStream is = conn.getInputStream(); 
      mBitmap = BitmapFactory.decodeStream(new FlushedInputStream(is));*/ 


      InputStream in = new java.net.URL(imageUrl).openStream(); 
      mBitmap = BitmapFactory.decodeStream(new FlushedInputStream (in)); 


      //this.mImageView.setTag(this.mUrl); 
      //mBitmap.recycle(); 

     } catch (MalformedURLException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     this.g = mBitmap; 

      return mBitmap; 

    } 

    public Bitmap myBitmap() { 
     Bitmap fg; 
     fg = (Bitmap) g; 

     return fg; 
    } 

    static class FlushedInputStream extends FilterInputStream { 
     public FlushedInputStream(InputStream inputStream) { 
      super(inputStream); 
     } 

     @Override 
     public long skip(long n) throws IOException { 
      long totalBytesSkipped = 0L; 
      while (totalBytesSkipped < n) { 
       long bytesSkipped = in.skip(n - totalBytesSkipped); 
       if (bytesSkipped == 0L) { 
        int b = read(); 
        if (b < 0) { 
         break; // we reached EOF 
        } else { 
         bytesSkipped = 1; // we read one byte 
        } 
       } 
       totalBytesSkipped += bytesSkipped; 
      } 
      return totalBytesSkipped; 
     } 
    } 






} 
+0

大家好......虽然我收到1个响应,我需要的东西是沿着我做的就行了。 – OneNation 2013-04-12 04:12:24

回答

0

无需实现这一点使用AsyncTask手动和这样你可以使用一个缓存库。 Android的查询是一个相当不错:http://code.google.com/p/android-query/

要与Android查询载入图片您可以使用您的ListView适配器的getView方法中下面的代码:

AQuery _aq = new AQuery(mActivity); 
_aq.id(R.id.icon).image("IMAGE_URI_TO_LOAD"); 

这应该更换holder.icon.setImageBitmap(bitmapList[position]);电话。

这将在imageview中加载,缓存和显示来自Uri的图像。如果图像已被缓存,它将自动从缓存加载。

有关如何使用这个库的图像加载,你可以点击这里了解更多信息:http://code.google.com/p/android-query/wiki/ImageLoading

+0

仍然没有解决我的问题。 mContext有错误。我用'this','Adapter.this','Adapter.java'代替,仍然有问题... – OneNation 2013-04-12 04:23:16

+0

我编辑了答案。尝试使用毫安而不是mContext – 2013-04-12 09:33:24

+0

无法正常工作。我不知道... @ __ @顺便说一句,我更新了我的帖子在DownloadImageTask.java上。我无法让它工作。 – OneNation 2013-04-12 09:50:28