1. 程式人生 > >Android之ListView優化(使用Lrucache,圖片滑動時使用預設圖片,停止時載入)

Android之ListView優化(使用Lrucache,圖片滑動時使用預設圖片,停止時載入)

注意:LruCache是有版本限制的,低版本的sdk需要在libs資料夾新增相應的support-4v檔案。
本文改造的大部分是參考http://www.iteye.com/topic/1118828,感謝。
不廢話直接上工程程式碼,內有關鍵註釋,專案就不上傳了,自己對照著上面網址改唄。


首先是Application檔案,負責建立圖片儲存資料夾:

複製程式碼
public class MyApp extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        File f = new
File(Environment.getExternalStorageDirectory()+"/TestSyncListView/pic/"); if (!f.exists()) { f.mkdirs(); } } }
複製程式碼


影象讀取工具類:

?
public class SyncImageLoaderUtil { private Object lock = new Object();  private boolean mAllowLoad = true private boolean firstLoad =
true private int mStartLoadLimit = 0 private int mStopLoadLimit = 0 final Handler handler = new Handler();  //    private HashMap<String, SoftReference<Drawable>> imageCache = new HashMap<String, SoftReference<Drawable>>();  private LruCache<String,Bitmap> mMemoryCache;
RunInOtherThread runInOutherThread;  public SyncImageLoaderUtil(Context context) {  super();  int memClass = ((ActivityManager)context.getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass(); int cacheSize = 1024 * 1024 *memClass / 8; mMemoryCache = new LruCache<String, Bitmap>(cacheSize){ @Override protected int sizeOf(String key, Bitmap value) { // TODO Auto-generated method stub return value.getRowBytes(); } }; runInOutherThread = new RunInOtherThread();  runInOutherThread.start();  public interface OnImageLoadListener {  public void onImageLoad(Integer t, Drawable drawable);  public void onError(Integer t);  public void setLoadLimit(int startLoadLimit, int stopLoadLimit) {  if (startLoadLimit > stopLoadLimit) {  //          LogUtil.i("test", startLoadLimit+"--錯誤---"+stopLoadLimit); return mStartLoadLimit = startLoadLimit;  mStopLoadLimit = stopLoadLimit;  public void restore() {  mAllowLoad = true firstLoad = true public void lock() {  mAllowLoad = false firstLoad = false public void unlock() {  mAllowLoad = true synchronized (lock) {  lock.notifyAll();  public void loadImage(Integer t, String imageUrl,  OnImageLoadListener listener) {  final OnImageLoadListener mListener = listener;  final String mImageUrl = imageUrl;  final Integer mt = t;  runInOutherThread.getHandler().post(new Runnable() {  @Override  public void run() {  if (!mAllowLoad) {  synchronized (lock) {  try lock.wait();  } catch (InterruptedException e) {  // TODO Auto-generated catch block  e.printStackTrace();  if (mAllowLoad && firstLoad) {  loadImage(mImageUrl, mt, mListener);  //                LogUtil.e("test", "原始開始:"+mStartLoadLimit+"原始當前位置:"+mt+"原始結束:"+mStopLoadLimit); if (mAllowLoad && mt <= mStopLoadLimit && mt >= mStartLoadLimit) {  //                  LogUtil.e("test", "開始:"+mStartLoadLimit+"當前位置:"+mt+"結束:"+mStopLoadLimit); loadImage(mImageUrl, mt, mListener); });  private void loadImage(final String mImageUrl, final Integer mt,  final OnImageLoadListener mListener) {  if (mImageUrl!=null && mMemoryCache.get(mImageUrl)!=null) {  //            SoftReference<Drawable> softReference = imageCache.get(mImageUrl);  final Drawable d = new BitmapDrawable(mMemoryCache.get(mImageUrl));  //            LogUtil.d("ppp", "drawable:"+d); if (d != null) {  handler.post(new Runnable() {  @Override  public void run() {  if (mAllowLoad) {  mListener.onImageLoad(mt, d);  });  return try final Drawable d = loadImageFromUrl(mImageUrl);  if (d != null) {  mMemoryCache.put(mImageUrl, ((BitmapDrawable)d).getBitmap()); handler.post(new Runnable() {  @Override  public void run() {  if (mAllowLoad) {  mListener.onImageLoad(mt, d);  });  } catch (IOException e) {  handler.post(new Runnable() {  @Override  public void run() {  mListener.onError(mt);  });  e.printStackTrace();  public static Drawable loadImageFromUrl(String url) throws IOException {  //DebugUtil.debug(url);  if (Environment.getExternalStorageState().equals(  Environment.MEDIA_MOUNTED)) {  File f = new File(Environment.getExternalStorageDirectory()  + "/Weiyu/pic/" + MD5Util.getMD5(url.getBytes()));  if (f.exists()) {  FileInputStream fis = new FileInputStream(f);  Drawable d = Drawable.createFromStream(fis, "src");  return d;  URL m = new URL(url);  InputStream i = (InputStream) m.getContent();  DataInputStream in = new DataInputStream(i);  FileOutputStream out = new FileOutputStream(f);  byte[] buffer = new byte[1024];  int byteread = 0 while ((byteread = in.read(buffer)) != -1) {  out.write(buffer, 0, byteread);  in.close();  out.close(); return loadImageFromUrl(url);  } else URL m = new URL(url);  InputStream i = (InputStream) m.getContent();  Drawable d = Drawable.createFromStream(i, "src");  return d;  }

  
執行緒輔助類:

?
public class RunInOtherThread { private static final String LOG_TAG = "RunInOtherThread" private LooperThread localThread = new LooperThread();  private boolean isRunning = true public Handler getHandler(){  return localThread.getHandler();  private class LooperThread extends Thread {  private Handler mHandler;  public void run() {  Looper.prepare();  mHandler = new Handler() {  public void handleMessage(Message msg) {  onReceiveMessage(msg.what);  };  Looper.loop();  Handler getHandler(){  return mHandler;  public void start(){  localThread.start();  public void quit(){  localThread.getHandler().getLooper().quit();  public void sendMessage(int what){  getHandler().sendEmptyMessage(what);  public Thread getThread(){  return localThread;  public void onReceiveMessage(int what){}; }

  
使用類:

?
// 例項化工具類 SyncImageLoaderUtil syncImageLoader = new SyncImageLoaderUtil(mContext); syncImageLoader.loadImage(position, model.mPic, imageLoadListener);//應用介面:引數一是載入圖片的位置;引數二是載入的ImageView;引數三是回撥介面 // map儲存的鍵是位置,值是listview對應位置的佈局 HashMap map = new HashMap(); map.put(position, convertView); SyncImageLoaderUtil.OnImageLoadListener imageLoadListener = new SyncImageLoaderUtil.OnImageLoadListener() { @Override public void onImageLoad(Integer t, Drawable drawable) { View view = (View) map.get(t); if (view != null) { ImageView iv = (ImageView) view.findViewById(R.id.image); iv.setBackgroundDrawable(drawable); } } @Override public void onError(Integer t) { // 圖片載入失敗 // 取得listview對應的位置的行的內容佈局 MusicModel model = (MusicModel) getItem(t); View view = mListView.findViewWithTag(model); if (view != null) { ImageView iv = (ImageView) view.findViewById(R.id.image); iv.setBackgroundResource(R.drawable.img_pic); } } }; // 實現類而且需要實現OnScrollListener介面 public void loadImage() { // 不要在這裡使用listview的getFirstVisiblePosition方法,位置不準 if (end >= getCount()) { end = getCount() - 1; } syncImageLoader.setLoadLimit(start, end); syncImageLoader.unlock(); } @Override public void onScrollStateChanged(AbsListView view, int scrollState) { // TODO Auto-generated method stub if (lodingView) { switch (scrollState) { case AbsListView.OnScrollListener.SCROLL_STATE_FLING: syncImageLoader.lock(); break; case AbsListView.OnScrollListener.SCROLL_STATE_IDLE: loadImage(); break; case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: syncImageLoader.lock(); break; default: break; } } } @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { // 在這裡取得的位置較準確,不過也會出現特殊的奇疤機型是不行的 // start與end是定義的變數 start = firstVisibleItem; end = firstVisibleItem + visibleItemCount; if (firstVisibleItem != 0) { // lodingView是控制變數,用來控制第一次進來檢視載入讀取圖片 lodingView = true; } else { lodingView = false; loadImage(); } }

相關推薦

AndroidListView優化(使用Lrucache圖片滑動使用預設圖片停止載入)

注意:LruCache是有版本限制的,低版本的sdk需要在libs資料夾新增相應的support-4v檔案。 本文改造的大部分是參考http://www.iteye.com/topic/1118828,感謝。 不廢話直接上工程程式碼,內有關鍵註釋,專案就不上傳了,自己對照著

Android開發listview優化+圖片非同步載入+避免圖片顯示閃爍(修改版)

小鹿路過此地。。心熱之下寫寫Android開發中的listview運用(閒的沒事幹,改動了一點程式碼,但實現功能不變) 小鹿學Android開發已有兩年多了,總算有一點點小收穫,雖算不上大牛大神級人物,但有些東西可以和一家一起分享一起交流一起學習一起進步...。還有,望檢視

Android Studio ListView的item點選事件彈出AlertDialog和item的滑動

首先看看效果圖: 點選彈出AlertDialog的確認框! (一)第一步,建立一個xml檔案顯示item的佈局 student_item.xml <?xml version="1.0" encoding="utf-8"?> <LinearLa

Android開發ListView 優化快取優化

通過平時對ListView的使用,目前我把ListView的優化分為以下幾個方面: 快取優化、資料優化、其他方面優化 0.未優化簡單程式碼 <span style="font-size:14

Android優化系列ListView優化老生常談

本文內容:adapter,listview的優化,RecycleBi,google大會推薦優化, 實現ListView的過程,Adapter起到了至關重要的作用,不僅僅因為getview()方法。那麼,先從Adapter說起~ Adapter:     它在ListView

AndroidListView的getItemViewType和getViewTypeCount

ldr get 思路 pre 簡單 erl 他會 add item PS:感覺這兩個方法其實還是很容易理解的,也算是給我其他兩個朋友寫的吧,幫他們搞清楚這兩個方法的用法和概念。同時還有一些小細節問題需要註意。 學習內容: 1.getItemViewType和get

AndroidWebView優化

前言 隨著app的迭代,嵌入的html5介面越來越多了,Webview這個強大元件引起的問題越發的多起來,例如: 1、WebView導致的oom問題 2、Android版本不同,採用了不同的核心,相容性crash 3、不同版本實現不同,甚至URI不規範也會引起不同程度的問題

AndroidListView的item獲取不到焦點

前兩天我在寫一個ListView,其中自定義的item中的控制元件有ImageView、TextView、Button,反正是比較複雜,寫完一整套流程後,真機一執行,詭異的事情出現了,點選item居然無響應。這怎麼回事呢?找了又找,程式碼看了一遍又一遍,沒問題

Android 效能優化

眾所周知,android裝置作為一種移動裝置,不管是cpu還是記憶體都無法跟pc裝置相提並論。這就意味著我們不能無限制地使用記憶體和cpu的資源,過多地使用記憶體會導致oom,過多地使用cpu資源,做大量的耗時任務,會導致手機變得異常卡頓,甚至無法響應出現ANR。所以我們在平常做開發時,一定要注意效

Android效能優化問題

1、UI優化 在xml佈局檔案中,合理選擇RelativeLayout、LinearLayout、FrameLayout,其中RelativeLayout會讓子View呼叫兩次onMeasure()方法,並且佈局複雜時,onMeasure也相對複雜,效率比較低;在LinearLayout中

AndroidListView分頁獲取網路資料(伺服器端)(一)

資料庫分頁: mysql:select pname from product limit 0,2;第一個引數是指要開始的地方,第二個引數是指每頁顯示多少條資料;注意:第一頁用0表示。 oracle:rownumber SqlServer:top 一、伺服器端 ①新建包com

Androidlistview新增資料篇

一、ListView:        1、 ListView通常有兩個職責:                                 1、向佈局填充資料                                 2、處理選擇點選等操作       2、ListView的建立需要3個元素:  

androidlistview分頁載入上拉重新整理、更新listview

==========系統方法實現上啦重新整理=========public class GreatToolsActivity extends Activity { private TextView tv; private ListView listtest;

原來操控介面可以這麼簡單----安卓上下滑動縮放頂部圖片左右滑動結束當前Activity及View柔和回彈效果

先上效果圖: 上傳圖片不能超過2M,費了好大勁。每一張gif動的有點快,將就看。 首先說原理: 為activity的xml檔案根佈局新增setOnTouchListener。上下滑動和左右滑動的所有操作都是在OnTouchListener的onTouch方法中實現的,通過

androidViewPager簡單實現區域性頁面滑動效果

-Viewpager能實現什麼效果? -實現左右滑動,切換view的效果。 -既可以實現整個頁面左右滑動,也可以實現同一個頁面中區域性左右滑動。 搞清楚viewpager的作用後,開始寫一個簡單例子,實現同一個頁面中區域性滑動的效果。 在coding前要做的準備工作 2

androidlistView快取機制

package com.example.day_05_06; import java.util.ArrayList; import java.util.List; import com.litsoft.General.General; import android.support.v7.app.ActionB

android用scrollview實現控制元件滑動固定效果

專案中最近用到需要佈局滑動到某一個地方的時候某個控制元件固定在螢幕頂部不動,就去研究了下,思路其實挺簡單的。我置頂的懸浮控制元件上邊還需要留個控制元件,比如搜尋框之類的,專案需求不一樣就留的不一樣,所以就研究了一下,網上也有很多,其實方法思路都一樣的,很簡單,自定義一下Sc

[Android 美] 那些你不知道的APK 瘦身讓你的APK更小

[Android 之美] APK 瘦身,減少APK的大小 讓我們的apk檔案儘可能更小,移除那些未使用的程式碼和資原始檔。本章節介紹瞭如何做到讓APK更小,效能更好,下載轉化率會更高,以及如何指定在構建APK過程中保留或移除專案中的程式碼和資源,在我們還

AndroidListView包含RadioButton的單選問題解決辦法

1.最簡潔的解決辦法。 adapter裡儲存當前選中的位置變數,getView方法裡,禁用radiobutton的點選事件,只通過listview的onItemClick事件設定選中位置變數,並且通過notifyDataSetChanged重新整理列表。getView方法裡

一起學AndroidListView

foo 每一個 .get 知識點 mar inf 布局 textview item 本文以一個小例子,簡述Android開發中ListView的相關應用,僅供學習分享使用。 概述 ListView是一個顯示可滾動項目列表的視圖組(view group),列表項通過適配器(A