Android ListView Holderを使用した最適化原理

5338 ワード

1つ ListView Holderを使用した最適化
adapperにget Viewの方法を上書きすると、例えば、
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			
			ViewHolder viewHolder = null;
			
			if (convertView == null) {
				viewHolder = new ViewHolder();
				
				convertView = mInflater.inflate(R.layout.listview_item, null);
				viewHolder.itemTextView = (TextView) convertView.findViewById(R.id.item_textview);
				viewHolder.itemImageView = (ImageView) convertView.findViewById(R.id.item_imageview);
				
				convertView.setTag(viewHolder);
			} else {
				viewHolder = (ViewHolder) convertView.getTag();
			}
			
			String value = String.valueOf( getItem(position) );
			viewHolder.itemTextView.setText( value );
			
			viewHolder.itemImageView.setImageResource(R.drawable.ic_launcher);
			
			return convertView;
		}
その中でconverViewは繰り返し使用します.ListViewの効率を高めるためです.しかし、非同期でデータをロードすると、対応するviewにバインドされると、itemの表示順序が乱れます.
疑問ですか
コード解析からconverViewは多重化されていますか?もしそうなら、どう多重しますか?
     もし複数の推計を使うなら、必ず1つのデータ構造をスタック「先入後出」のように保存します.これらのViewを繰り返し使う必要がある場合、現在使われていないViewを順次取り出します.
二番目 ソースコードを分析し、疑問を解決する
1.adapperはset Adapterを通じてListViewと結び付けられています.まずListView.setAdapterの部分のソースコードを見にきます.
     public void setAdapter(ListAdapter adapter) {
        ......

        if (mHeaderViewInfos .size() > 0|| mFooterViewInfos.size() > 0) {
            mAdapter = new HeaderViewListAdapter(mHeaderViewInfos , mFooterViewInfos , adapter);
        } else {
            mAdapter = adapter;
        }
	 ......
     }
   ListViewでは、入ってきたadapperをListViewのグローバル変数mAdapterに割り当てていることがわかった.
     ここで使うのはアダプターのモードで、Viewは具体的にどのようにして導入されたAdapterを作成しますか?
     ListViewを作成するには必ずmAdapter.get Viewのメソッドを呼び出しましたが、ListViewではグローバル検索が見つかりませんでした.それはListViewの父の種類の中で探して、その父の種類はAbs ListViewで、同じように'mAdapter.get View'を検索して、Abs ListView.obtainView()の方法の中で探して、obtainViewコードを調べます:
2.Abs ListView.obtainViewの一部のソースコード:
    View obtainView( int position, boolean[] isScrap) {
        isScrap[0] = false ;
        View scrapView;

        scrapView = mRecycler .getScrapView(position);

        View child;
        if (scrapView != null) {
                        ......

            child = mAdapter .getView(position, scrapView, this);
            ......
	}
	......
    }
   
    getViewの第二のパラメータ、すなわちAdapter.getViewが見つかりました.
 要点 
  position、View convertView、View Group parent )のconverViewの由来は、もとは通過です.
 mRecycler 
 .get ScripViewで取得したものは、グローバル変数mRecyclerに続いていきます.
3.mRecycler定義
    /**
     * The data set used to store unused views that should be reused during the next layout
     * to avoid creating new ones
     */
    final RecycleBin mRecycler = new RecycleBin();
4.RecycleBinのソースコードを引き続き調べてください.この種類はAbs ListViewの内部類で、2の中で使われています. 
mRecycler 
  .get ScripView(position) 
ソースの一部は以下の通りです.
    class RecycleBin {
	......

        /**
         * Views that were on screen at the start of layout. This array is populated at the start of
         * layout, and at the end of layout all view in mActiveViews are moved to mScrapViews.
         * Views in mActiveViews represent a contiguous range of Views, with position of the first
         * view store in mFirstActivePosition.
         */
        private View[] mActiveViews = new View[0];

        /**
         * Unsorted views that can be used by the adapter as a convert view.
         */
        private ArrayList<View>[] mScrapViews;

        private int mViewTypeCount;

        private ArrayList<View> mCurrentScrap;

	......

        /**
         * @return A view from the ScrapViews collection. These are unordered.
         */
        View getScrapView(int position) {
            ArrayList<View> scrapViews;
            if (mViewTypeCount == 1) {
                scrapViews = mCurrentScrap;
                int size = scrapViews.size();
                if (size > 0) {
                    return scrapViews.remove(size - 1);
                } else {
                    return null;
                }
            } else {
                int whichScrap = mAdapter.getItemViewType(position);
                if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
                    scrapViews = mScrapViews[whichScrap];
                    int size = scrapViews.size();
                    if (size > 0) {
                        return scrapViews.remove(size - 1);
                    }
                }
            }
            return null;
        }
	
	......
    }
5 RecycleBinが使用するデータ構造を分析する.
全部で二つの記憶構造があります.それぞれActiveViewとSrapViewです.
ActiveViewは現在、画面(携帯電話表示領域)にViewを表示しています.画面を移動するとScripViewに保存されます.
ScripViewは、現在の画面(携帯電話の表示領域)に表示されているViewを記憶しています.これらのviewは回収に相当します.再要求された場合は、メモリから取り出して繰り返し使用します.
三つの結論
1.ListViewは、Adapter.getViewの第二のパラメータにより、作成されたViewを繰り返し利用して効率を向上させることができます.
2.繰り返し使うviewはAbs ListViewの内部クラスです.
RecycleBin管理は、開発者が使用するために、adapper.getViewの第二パラメータを呼び出すことによって行われます.
四拡張
Androidは自分でListViewを書いてその原理を勉強します.3 ItemClick、Item LongClick、View多重です. 原理はListViewと同じです.簡略版です.
転載は出典を明記してください.http://blog.csdn.net/love_world_/article/details/8112827
2013-03-31更新と自分の手の例接続