日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ListView优化

發布時間:2024/8/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ListView优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Android性能優化-ListView
ListView的優化主要分為以下幾點

1 convertView的復用
ListView每次滾動都會調用getView方法,所以優化getVieiw是重中之重

convertView介紹
convertView是剛剛滾動出可見區域的View的引用,此時它已經不可見,所以應該被復用以減少View的創建

優化代碼
View view = null;//getView方法要返回的View
if(convertView == null){//如果當前沒有可以復用的View
view = LayoutInflater.from(context).inflate(resourceId,null);//那么就從XML文件生成一個View
}else{//否則
view = convertView;//就使用可以復用的View
}
優化原因
LayoutInflater.inflate(resourceId,View)這個方法是用來通過pull的解析方式從XML文件生成一個View對象的,如果有成千上萬
個Viwe都要去解析XML生成View,會非常消耗性能

2ViewHolder的使用
優化代碼
ViewHolder viewHolder = null;
View view = null;//getView方法要返回的View
if(convertView == null){//如果當前沒有可以復用的View
viewHolder = new ViewHolder();
view = LayoutInflater.from(context).inflate(resourceId,null);//那么就從XML文件生成一個View
viewHolder.resourceViewName = view.findViewById(resouceViewId);//從XML中找到對應的View
view.setTag(viewHolder);//將ViewHolder設置在當前ItemView的tag里面
}else{//否則
view = convertView;//就使用可以復用的View
viewHolder = (ViewHolder)convertView.getTag();//從復用的View中取出viewHoder
}
viewHolder

class ViewHolder {
TextView name;
}
優化原因
findViewById這個方法是從ViewGroup的子View里面循環遍歷找id與給出的ID相同的子View,還是比較耗時的,

/*ViewGroup的FindViewByID源碼/

/*** {@hide}*/ @Override protected <T extends View> T findViewTraversal(@IdRes int id) {if (id == mID) {return (T) this;}final View[] where = mChildren;final int len = mChildrenCount;for (int i = 0; i < len; i++) {View v = where[i];if ((v.mPrivateFlags & PFLAG_IS_ROOT_NAMESPACE) == 0) {v = v.findViewById(id);if (v != null) {return (T) v;}}}return null; }

3圖片"三級緩存"加載優化
闡述
圖片加載順序,應該為,內存–本地–網絡

1、內存緩存 優先加載,速度最快
2、本地緩存 次優先加載 速度稍快
3、網絡緩存 最后加載 速度由網絡速度決定(浪費流量)
代碼(緩存到本地,從網絡獲取就不寫了)
主要寫一下緩存到內存中的方法,
據說以前使用HashMap<String,SoftReference>的方法緩存,不過不好用了,現在大多都用
LruCache,

public class MemoryCache {
private LruCache<String,Bitmap> mLruCache = null;
public MemoryCache(){
long maxMemory = Runtime.getRuntime().maxMemory();//最大內存 默認是16M
mLruCache = new LruCache<String,Bitmap>((int)(maxMemory/8)){
@Override
protected int sizeOf(String key, Bitmap value) {
//int byteCount = value.getByteCount();
//得到圖片的字節數
int byteCount = value.getRowBytes() * value.getWidth();
return byteCount;
}
};
}
//從內存獲取
public Bitmap getFromMemory(String url){
return mLruCache.get(url);
}
//緩存到內存
public void setToMemory(String url,Bitmap bitmap){
mLruCache.put(url,bitmap);
}
}
優化原因
從網絡加載圖片或者本地加載圖片都比較耗時,加上Android16ms的刷新UI頻率,會造成卡頓
從內存獲取速度相對較快,以上只是放入內存的方法,當然壓縮什么的就沒有寫,只是簡單介紹存入內存的原理

4圖片加載再次優化
導論
很多情況下ListView需要加載顯示網絡圖片,我們盡量不要在ListView滑動的時候加載網絡圖片,
那樣會使ListView變得卡頓所以我們要監聽ListView的狀態,如果ListView滑動(SCROLL_STATE_TOUCH_SCROLL)
或者猛滑(SCROLL_STATE_FLING)的時候,停止加載圖片,否則加載圖片

優化代碼
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == OnScrollListener.SCROLL_STATE_IDLE) {//list停止滾動時加載圖片
loadImage(startPos, endPos);// 異步加載圖片 ,只加載可以看到的圖片
}
}

@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
//設置當前屏幕顯示的起始pos和結束pos
startPos = firstVisibleItem;
endPos = firstVisibleItem + visibleItemCount;
if (endPos >= totalItemCount) {
endPos = totalItemCount - 1;
}
}
});
優化原因
從用戶的角度講,快速滑動的時候,用戶不需要看到當前內容

5 onClickListener處理
導論
有時候出了onItemClickListener之外我們還會用到Item上其他位置的點擊事件
一般情況下我們是在getView方法中,一個一個設置,就像

holder.img.setOnClickListener(new onClickListener());
這樣每個都設置了一個新的OnClickListener對象,不太好

優化方案
直接在ViewHolder中設置一個position,然后viewHolder implements OnClickListener

class ViewHolder implements OnClickListener{
int position;
TextView name;

public void setPosition(int position){ this.position = position; } @Override public void onClick(View v) { switch (v.getId()){ //XXXX } }

}
然后再getView中設置的時候設置自己就行了

ViewHolder viewHolder = null;
View view = null;//getView方法要返回的View
if(convertView == null){//如果當前沒有可以復用的View
viewHolder = new ViewHolder();
view = LayoutInflater.from(context).inflate(resourceId,null);//那么就從XML文件生成一個View
viewHolder.resourceViewName = view.findViewById(resouceViewId);//從XML中找到對應的View
viewHolder.setPosition(position);//設置位置
viewHolder.name.setOnClickListener(viewHolder);//設置ClickListener
view.setTag(viewHolder);//將ViewHolder設置在當前ItemView的tag里面
}else{//否則
view = convertView;//就使用可以復用的View
viewHolder = (ViewHolder)convertView.getTag();//從復用的View中取出viewHoder
}

6 總結
總之,宗旨就是少在getView里面new對象,做耗時操作

總結

以上是生活随笔為你收集整理的ListView优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。