Android性能最適化のListView性能向上テクニック

8126 ワード

ListViewの最適化は常に一般的な問題であり、面接でも通常の開発でもListViewは無視されません.では、この文章では、ListViewのパフォーマンスを最大化する方法を見てみましょう.
  • 1.adapterのgetViewメソッドでは、論理
  • をできるだけ少なく使用します.
  • 2.GC
  • はできるだけ避ける
  • 3.スライド時に画像
  • をロードしない
  • 4.ListViewのscrollingCacheとanimateCacheをfalse
  • に設定
  • 5.itemのレイアウトレベルは、焼くほど
  • になります.
  • 6.ViewHolder
  • の使用
    1.adapterでのgetViewメソッドでは論理の使用を最小限に抑える
    getView()に論理コードを書きすぎないでください.たとえば、次のような場所に置くことができます.
    最適化前の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   ,  getView             ,        
            RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
            holder.EventPoster.setLayoutParams(imageParams);
    
            return convertView;
    }

    最適化された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);
                //        ,           ,      
                RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(measuredwidth, rowHeight);
                holder.EventPoster.setLayoutParams(imageParams);
                convertView.setTag(holder);
        } else {
                holder = (ViewHolder) convertView.getTag();
        }
    
        //          getter            ,                
        holder.ThreeDimension.setVisibility(object.getVisibility());
    
        return convertView;
    }

    2.GCゴミ回収器
    大量のオブジェクトを作成するとGCは頻繁に実行されるのでgetView()メソッドでは多くのオブジェクトを作成しないでください.最も最適化されているのは、ViewHolder以外のオブジェクトを作成しないでください.もしあなたのロゴに「GC has freed some memory」が頻繁に現れていることを発見したら、あなたのプログラムに問題があるに違いありません.a)itemレイアウトの階層が深すぎるかどうかを確認できますb)getView()メソッドにc)ListViewのレイアウトプロパティが多数存在するかどうかを確認できます.
    3.画像のロード
    もしあなたのListViewにネットからダウンロードした画像を表示する必要があるならば、私達はListViewがスライドする時に画像をロードしないでください、それではListViewがカートンになることができて、だから私達は更にリスナーの中でListViewの状態を傍受する必要があって、もしスライドする時、画像を追加することを停止して、もしスライドしていないならば、画像をロードし始めます
    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です.ビューに自分のdrawingをcacheに保存させることができます(bitmapとして保存されます).そうすれば、次回ビューを表示するときに再描画するのではなく、cacheから取り出すことができます.デフォルトではdrawing cahceは無効です.メモリが消費されるためですが、絵よりもスムーズに描かれています.ListViewではscrollingCacheがデフォルトでオンになっており、手動でオフにすることができます.
    animateCache:ListViewではデフォルトでanimateCacheがオンになっています.これによりメモリが大量に消費されるため、頻繁にGCが呼び出され、手動で閉じることができます.
    最適化前のListView
    "@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" /> 
    
    
    

    最適化されたListView
    "@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のレイアウトの深さを減らす
    ListViewをスライドさせると、測定と描画が直接発生するため、itemレイアウトの深さを最小限に抑える必要があります.そのため、不要なレイアウトネスト関係を削除する必要があります.itemレイアウトの深さを減らす
    6.ViewHolderの使用
    これはよく知っているはずですが、このViewHolderを軽視しないでください.ListViewのパフォーマンスを大幅に向上させることができます.
    ListViewの最適化はもう終わりました.もしあなたのプロジェクトの中で、これらの基本的な最適化がまだできていないならば、あなたのListViewは問題があって、まだ大きな向上潜在力があります.後でListViewを使うときは、必ずこれらの点を考慮して、その最大の性能を発揮しなければなりません.