最近在做ListView分页显示,其中包括图片 和文字(先下载解析文字内容,再异步加载图片)发现每次点击下一页后,文字内容加载完毕,马上向下滑动,由于这时后台在用线程池异步下载图片,我每页有20条,也就是20张图片,会导致listview滑动卡顿!
这是用户不想看到的,我参考了网易新闻和电子市场等应用,发现它们都是只加载屏幕内的图片,不现实的不加载,于是我也仿照做了一个。我是菜鸟,我承认 呵呵,虽然不见得完全和他们的一样,但是确实解决了翻页时那一刻的卡顿现象。
因为未发现网上有相关文章,希望对朋友们有用~
下面是相关代码(分页的就没放):
/** * list滚动监听 */ listView.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub // 异步加载图片 if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {//list停止滚动时加载图片 pageImgLoad(_start_index, _end_index); } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // TODO Auto-generated method stub //设置当前屏幕显示的起始index和结束index _start_index = firstVisibleItem; _end_index = firstVisibleItem + visibleItemCount; if (_end_index >= totalItemCount) { _end_index = totalItemCount - 1; } } });
/** * 只加载from start_index to end_index 的图片 * @param start_index * @param end_index */ private void pageImgLoad(int start_index, int end_index) { for (; start_index < end_index; start_index++) { HashMap<String, Object> curr_item = adapter.getItem(start_index); if (curr_item.get(Constant.NEWS_ICON_URL) != null && curr_item.get(Constant.NEWS_ICON) == null) { loadImage(curr_item); } } }
异步加载图片代码,这里我之前使用的是AsyncTask,但是继承AsyncTask后不能被执行多次,所以我改用了线程呼叫handler更新UI:
/** * 异步加载图片 * @param curr_item */ private void loadImage(final HashMap<String, Object> curr_item) { executorService.submit(new Runnable() { public void run() { try { Drawable curr_icon = null; String icon_URL = (String) curr_item .get(Constant.NEWS_ICON_URL); String newsId = (String) curr_item.get(Constant.NEWS_ID); if (imageCache.containsKey(icon_URL)) {//软引用 SoftReference<Drawable> softReference = imageCache .get(icon_URL); curr_icon = softReference.get(); System.out.println("CASE USING SoftReference!!!!!!!!!!!!!!!!!!!!"); } if (curr_icon == null) { HttpUtils hu = new HttpUtils(); FileUtils fu = new FileUtils(); if (hu.is_Intent(Home_Activity.this)) { fu.write2LocalFromIS(Home_Activity.this, newsId + Constant.SAVE_NEWS_ICON_NAME + Constant.SAVE_IMG_SUFFIX, hu.getISFromURL(icon_URL)); } // 从本地加载图片 如果没网则直接加载本地图片 curr_icon = fu.readDrawableFromLocal( Home_Activity.this, newsId + Constant.SAVE_NEWS_ICON_NAME + Constant.SAVE_IMG_SUFFIX); imageCache.put(icon_URL, new SoftReference<Drawable>( curr_icon)); } curr_item.put(Constant.NEWS_ICON, curr_icon); // UI交给handler更新 Message msg = _viewHandler.obtainMessage(); msg.arg1 = Constant.MSG_LIST_IMG_OK; msg.sendToTarget(); } catch (Exception e) { throw new RuntimeException(e); } } }); }
handler代码:
Handler _viewHandler = new Handler() {
@Override public void handleMessage(Message msg) { switch (msg.arg1) { case Constant.MSG_LIST_IMG_OK: // 更新UI adapter.notifyDataSetChanged(); break; } super.handleMessage(msg); } };
上个图吧: