安卓listview照片重复显示解决办法

类似游戏资讯的一个小项目

效果图:

listview页面

点击listview页面的item进入详细页面





1----------首先粘贴异步请求图片并处理的类  

AsyncImageLoader类

public class AsyncImageLoader {
	private HashMap<String, SoftReference<Drawable>> imageCache;

	public AsyncImageLoader() {
		imageCache = new HashMap<String, SoftReference<Drawable>>();
	}

	public Drawable loadDrawable(final String imageUrl, final ImageCallback imageCallback) {
		if (imageCache.containsKey(imageUrl)) {
			SoftReference<Drawable> softReference = imageCache.get(imageUrl);
			Drawable drawable = softReference.get();
			if (drawable != null) {
				return drawable;
			}
		}
		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
			}
		};
		new Thread() {
			@Override
			public void run() {
				Drawable drawable = loadImageFromUrl(imageUrl);
				imageCache.put(imageUrl, new SoftReference<Drawable>(drawable));
				Message message = handler.obtainMessage(0, drawable);
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}

	public static Drawable loadImageFromUrl(String url) {
		URL m;
		InputStream i = null;
		try {
			m = new URL(url);
			i = (InputStream) m.getContent();
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		Drawable d = Drawable.createFromStream(i, "src");
		return d;
	}

	public interface ImageCallback {
		public void imageLoaded(Drawable imageDrawable, String imageUrl);
	}
}


2------其次粘贴上我的listview所用适配器adapter类,这个主要主力listview与数据的绑定。

这里我的数据全是从网络请求的,imageview传得是一个图片的http的url,下面是代码:

public class news_adapter extends BaseAdapter {

	int width;
	int height;

	private ListView listView;
	private List<news_model> news_list;

	private AsyncImageLoader asyncImageLoader;

	private Context my_context;

	public news_adapter(List<news_model> news_list, Context text, ListView listView) {
		this.news_list = news_list;
		this.my_context = text;
		this.listView = listView;
		asyncImageLoader = new AsyncImageLoader();
		WindowManager wm = ((Activity) my_context).getWindowManager();

		width = wm.getDefaultDisplay().getWidth();
		height = wm.getDefaultDisplay().getHeight();

	}

	@Override
	public int getCount() {

		return news_list.size();
	}

	@Override
	public Object getItem(int position) {
		// TODO Auto-generated method stub
		return news_list.get(position);
	}

	@Override
	public long getItemId(int position) {
		// TODO Auto-generated method stub
		return position;
	}

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

		String image_url = ((news_model) news_list.get(position)).getImage_url();
		View news_item_view = null;
		gandler holder = null;
		if (convertView == null) {
			news_item_view = View.inflate(my_context, R.layout.news_item, null);
			holder = new gandler();
			holder.imagev = (ImageView) news_item_view.findViewById(R.id.news_image_v);
			holder.titlev = (TextView) news_item_view.findViewById(R.id.news_title_v);
			holder.timev = (TextView) news_item_view.findViewById(R.id.news_up_time);

			news_item_view.setTag(holder);

			

		} else {
			news_item_view = convertView;
			holder = (gandler) news_item_view.getTag();

		}

		holder.imagev.setTag(image_url);
		// (holder.imagev).setImageBitmap(((news_model)news_list.get(position)).getImg_bitmap());;
		(holder.titlev).setText(((news_model) news_list.get(position)).getNews_title());
		(holder.timev).setText(timeStampToDate(((news_model) news_list.get(position)).getUpdate_time()));
		Drawable cacheimage = asyncImageLoader.loadDrawable(image_url, new ImageCallback() {

			@Override
			public void imageLoaded(Drawable imageDrawable, String imageUrl) {

				// TODO Auto-generated method stub
				ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
				if (imageViewByTag != null) {

					imageViewByTag.setImageDrawable(imageDrawable);
				}
			}
		});

		if (cacheimage == null) {

		} else {
			holder.imagev.setImageDrawable(cacheimage);
		}
		
		
		
		
		return news_item_view;
	}

	public class mtthread extends Thread {

		@Override
		public void run() {

		}
	}

	static class gandler {
		public ImageView imagev;
		public TextView titlev;
		public TextView timev;

	}

	public static String timeStampToDate(String timeStamp_str) {

		long timeStamp = Long.parseLong(timeStamp_str);
		Date date = new Date(timeStamp * 1000);
		SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr = simpleDateFormat.format(date);
		return dateStr;
	}

}
3-----adater给listview所绑定的数据--list数组实在mainactivity中异步请求并设置到adapter中的,主要代码如下;get_news方法就是异步请求并返回一个list数组的————在这里着重提一下,在activity中做耗时的操作(包括网络请求),一定要异步(比如重开新线程,方法很多;不会的百度一下,一万个人急着告诉你!)。。。为什么要异步呢?原因是activity中一般都是主线程执行你的代码,包括“画”界面,如果你的耗时操作放在activity中不开线程,并且耗时操作在画图之前(不如更新一个textview的text等),那么有可能造成主线程连你的界面都画不出来。

list_view = (ListView) findViewById(R.id.news_listView);

		
		get_news();
	
		load_more_view = getLayoutInflater().inflate(R.layout.loadmore_view, null);
		list_view.addFooterView(load_more_view);
		adapt = new news_adapter(news_list, this,list_view);
		
		

		list_view.setAdapter(adapt);

4------下面到重点了,我的listview的item上的照片一直重复六个图片,但是我经过调试发现的确每条news都请求到自己的图片了呀,为什么会这样了?原因就出在adaoter的view复用中。下面上没改之前的代码

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

		String image_url = ((news_model) news_list.get(position)).getImage_url();
		View news_item_view = null;
		gandler holder = null;
		if (convertView == null) {
			news_item_view = View.inflate(my_context, R.layout.news_item, null);
			holder = new gandler();
			holder.imagev = (ImageView) news_item_view.findViewById(R.id.news_image_v);
			holder.titlev = (TextView) news_item_view.findViewById(R.id.news_title_v);
			holder.timev = (TextView) news_item_view.findViewById(R.id.news_up_time);

			news_item_view.setTag(holder);

			holder.imagev.setTag(image_url);

		} else {
			news_item_view = convertView;
			holder = (gandler) news_item_view.getTag();

		}

		
		// (holder.imagev).setImageBitmap(((news_model)news_list.get(position)).getImg_bitmap());;
		(holder.titlev).setText(((news_model) news_list.get(position)).getNews_title());
		(holder.timev).setText(timeStampToDate(((news_model) news_list.get(position)).getUpdate_time()));
		Drawable cacheimage = asyncImageLoader.loadDrawable(image_url, new ImageCallback() {

			@Override
			public void imageLoaded(Drawable imageDrawable, String imageUrl) {

				// TODO Auto-generated method stub
				ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
				if (imageViewByTag != null) {

					imageViewByTag.setImageDrawable(imageDrawable);
				}
			}
		});

		if (cacheimage == null) {

		} else {
			holder.imagev.setImageDrawable(cacheimage);
		}
		
		
		
		
		return news_item_view;
	}
看到了么?我把
<span style="font-family:SimHei;font-size:24px;color:#ff0000;">holder.imagev.setTag(image_url);</span>
放在
<span style="font-family:SimHei;font-size:24px;color:#ff0000;">if (convertView == null) {</span>
里,而这个方法只在发现没有可复用的item的别问是才执行(生成一个view),而我的屏幕只能显示6个item,所以这个方法走了六次,只请求了六张图片,循环放着item上,解决方法相信你已经知道了,把
<span style="font-family:SimHei;font-size:24px;color:#ff0000;">holder.imagev.setTag(image_url);</span>
放外边就行了,让他每次item滚动出来都执行,而不是发现没有可复用的item时才执行,代码如下:


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

		String image_url = ((news_model) news_list.get(position)).getImage_url();
		View news_item_view = null;
		gandler holder = null;
		if (convertView == null) {
			news_item_view = View.inflate(my_context, R.layout.news_item, null);
			holder = new gandler();
			holder.imagev = (ImageView) news_item_view.findViewById(R.id.news_image_v);
			holder.titlev = (TextView) news_item_view.findViewById(R.id.news_title_v);
			holder.timev = (TextView) news_item_view.findViewById(R.id.news_up_time);

			news_item_view.setTag(holder);

			

		} else {
			news_item_view = convertView;
			holder = (gandler) news_item_view.getTag();

		}

		holder.imagev.setTag(image_url);
		// (holder.imagev).setImageBitmap(((news_model)news_list.get(position)).getImg_bitmap());;
		(holder.titlev).setText(((news_model) news_list.get(position)).getNews_title());
		(holder.timev).setText(timeStampToDate(((news_model) news_list.get(position)).getUpdate_time()));
		Drawable cacheimage = asyncImageLoader.loadDrawable(image_url, new ImageCallback() {

			@Override
			public void imageLoaded(Drawable imageDrawable, String imageUrl) {

				// TODO Auto-generated method stub
				ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
				if (imageViewByTag != null) {

					imageViewByTag.setImageDrawable(imageDrawable);
				}
			}
		});

		if (cacheimage == null) {

		} else {
			holder.imagev.setImageDrawable(cacheimage);
		}
		
		
		
		
		return news_item_view;
	}
至此问题解决,喜欢的请点个赞。么么哒!!



更多问题,欢迎加群讨论:qq群 :565191947



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值