Android性能優(yōu)化之提高ListView性能的技巧

ListView優(yōu)化一直是一個老生常談的問題,不管是面試還是平常的開發(fā)中,ListView永遠不會被忽略掉,那么這篇文章我們來看看如何最大化的優(yōu)化ListView的性能。

1.在adapter中的getView方法中盡量少使用邏輯
2.盡最大可能避免GC
3.滑動的時候不加載圖片
4.將ListView的scrollingCache和animateCache設置為false
5.item的布局層級越燒越好
6.使用ViewHolder

1.在adapter中的getView方法中盡量少使用邏輯

不要在你的getView()中寫過多的邏輯代碼,我們可以將這些代碼放在別的地方,例如:

優(yōu)化前的getView():

@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
        Object current_event = mObjects.get(position);
        ViewHolder holder = null;
        if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.row_event, null);
                holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
                holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
                convertView.setTag(holder);

        } else {
                holder = (ViewHolder) convertView.getTag();
        }

       //在這里進行邏輯判斷,這是有問題的 
        if (doesSomeComplexChecking()) {
                holder.ThreeDimention.setVisibility(View.VISIBLE);
        } else {
                holder.ThreeDimention.setVisibility(View.GONE); 
        }

        // 這是設置image的參數(shù),每次getView方法執(zhí)行時都會執(zhí)行這段代碼,這顯然是有問題的
        RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
        holder.EventPoster.setLayoutParams(imageParams);

        return convertView;
}

優(yōu)化后的getView():

@Override
public View getView(int position, View convertView, ViewGroup paramViewGroup) {
    Object object = mObjects.get(position);
    ViewHolder holder = null;

    if (convertView == null) {
            holder = new ViewHolder();
            convertView = inflater.inflate(R.layout.row_event, null);
            holder.ThreeDimension = (ImageView) convertView.findViewById(R.id.ThreeDim);
            holder.EventPoster = (ImageView) convertView.findViewById(R.id.EventPoster);
            //設置參數(shù)提到這里,只有第一次的時候會執(zhí)行,之后會復用 
            RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
            holder.EventPoster.setLayoutParams(imageParams);
            convertView.setTag(holder);
    } else {
            holder = (ViewHolder) convertView.getTag();
    }

    // 我們直接通過對象的getter方法代替剛才那些邏輯判斷,那些邏輯判斷放到別的地方去執(zhí)行了
    holder.ThreeDimension.setVisibility(object.getVisibility());

    return convertView;
}

2.GC 垃圾回收器

當你創(chuàng)建了大量的對象的時候,GC就會頻繁的執(zhí)行,所以在getView()方法中不要創(chuàng)建很多的對象,最好的優(yōu)化是,不要在ViewHolder以外創(chuàng)建任何對象,如果你的你的log里面發(fā)現(xiàn)“GC has freed some memory”頻繁出現(xiàn)的話,那你的程序肯定有問題了。你可以檢查一下:
a) item布局的層級是否太深
b) getView()方法中是否有大量對象存在
c) ListView的布局屬性

3.加載圖片

如果你的ListView中需要顯示從網絡上下載的圖片的話,我們不要在ListView滑動的時候加載圖片,那樣會使ListView變得卡頓,所以我們需要再監(jiān)聽器里面監(jiān)聽ListView的狀態(tài),如果滑動的時候,停止加載圖片,如果沒有滑動,則開始加載圖片

listView.setOnScrollListener(new OnScrollListener() {

            @Override
            public void onScrollStateChanged(AbsListView listView, int scrollState) {
                    //停止加載圖片 
                    if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING) {
                            imageLoader.stopProcessingQueue();
                    } else {
                    //開始加載圖片
                            imageLoader.startProcessingQueue();
                    }
            }

            @Override
            public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
                    // TODO Auto-generated method stub

            }
    });

4.將ListView的scrollingCache和animateCache設置為false

scrollingCache: scrollingCache本質上是drawing cache,你可以讓一個View將他自己的drawing保存在cache中(保存為一個bitmap),這樣下次再顯示View的時候就不用重畫了,而是從cache中取出。默認情況下drawing cahce是禁用的,因為它太耗內存了,但是它確實比重畫來的更加平滑。而在ListView中,scrollingCache是默認開啟的,我們可以手動將它關閉。

animateCache: ListView默認開啟了animateCache,這會消耗大量的內存,因此會頻繁調用GC,我們可以手動將它關閉掉

優(yōu)化前的ListView

<ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:divider="@color/list_background_color"
        android:dividerHeight="0dp"
        android:listSelector="#00000000"
        android:smoothScrollbar="true"
        android:visibility="gone" /> 

優(yōu)化后的ListView

<ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:divider="@color/list_background_color"
        android:dividerHeight="0dp"
        android:listSelector="#00000000"
        android:scrollingCache="false"
        android:animationCache="false"
        android:smoothScrollbar="true"
        android:visibility="gone" />

5.減少item的布局的深度

我們應該盡量減少item布局深度,因為當滑動ListView的時候,這回直接導致測量與繪制,因此會浪費大量的時間,所以我們應該將一些不必要的布局嵌套關系去掉。減少item布局深度

6.使用ViewHolder

這個大家應該非常熟悉了,但是不要小看這個ViewHolder,它可以大大提高我們ListView的性能

ListView的優(yōu)化我們已經講完了,如果在你的項目中,這些基本優(yōu)化你還沒有做到的話,那么你的ListView是有問題的,還有很大的提升潛力,以后再使用ListView的時候,一定要將這幾點考慮進去,發(fā)揮它的最大的性能。


360°Android app全方位性能調優(yōu).png

QQ圖片20190110202918.jpg

QQ圖片20190110202923.png

+qq群:457848807。獲取以上高清技術思維圖,以及相關技術的免費視頻學習資料。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容