我和这个人有同样的问题 Listview 显示错误的图像
我看到了我必须缓存它的解决方案。但是在我的缓存中,我不确定如何应用解决方案中给出的缓存。我不断收到错误。
我怀疑这是我有问题的部分:
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
}
下载ImageTask.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;
}
}
}