在使用ListView顯示數據的時候,定義一個適配器,而後重寫getView()方法,這時經過LOG日誌分析會發現getView()方法會被執行屢次。經過上網查詢資料得出ide
緣由在於View在Draw的時候分爲兩個階段,measure和layout,在measure階段得時候,主要是爲了計算兩個參數,height和width,這是一個遞歸的過程,DecorView開始依次調用本身元素的measure,計算完成兩個參數就開始layout,而後調用draw,對於ListView,每個Item都會調用measure(),而在這個過程當中getView()和getCont()會被調用,並且根據用戶的需求,可能有屢次調用url
多組調用的緣由:spa
這是因爲layout中定義的ListView或者其父元素的height和width的屬性決定了,fill_parent,計算會簡單一點,可是Wrap_content的計算會多一點,至於自適應會一直考量Item的寬和高,根據內容,計算高度,這個measure可能會反覆執行。日誌
解決方法,就是listview的大小要肯定,例如使用match_parent。
方法一:
在listview外面套一層RelativeLayout,將listview高度設置爲match_parent。
code
方法二:
在listview外面套一層 LinearLayout,將listview高度設置爲0dip。
weight設爲1。xml
這樣簡單的listview是有效的,可是item若是是複雜的xml,很難實現,或者說沒法實現。若是是scrollview嵌套listview和gridview也不會成功。遞歸
究其緣由,無非是listview要動態計算有多少個view顯示在裏面,因此須要屢次onMeasure,最後才onLayout,而onMeasure可能須要執行屢次。這不就好了,咱們在adapt裏面的getview中,判斷是否在onmeasure裏,若是在。(在adapter的getView()方法中,對isOnMeasure()的值進行判斷,若是爲ture,提早return convertView;)ip
首先重寫 listviewget
public class NoScrollListview extends ListView{ //設置判斷來防止重複執行getView(); public boolean isOnMeasure = false; public NoScrollListview(Context context) { super(context); } public NoScrollListview(Context context, AttributeSet attrs) { super(context, attrs); } /** * 設置不滾動 */ public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { isOnMeasure = true; int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { isOnMeasure = false; super.onLayout(changed, l, t, r, b); } }
而後在Adapter中判斷it
public View getView(int position, View convertView, ViewGroup parent) { ViewHolder vh; if (convertView == null) { convertView = inflater.inflate(R.layout.inflate_griditem_mainpage_wall_and_lock, null); vh = new ViewHolder(); vh.iv = (ImageView) convertView.findViewById(R.id.image_griditem2); convertView.setTag(vh); }else { vh = (ViewHolder) convertView.getTag(); } //關鍵代碼 if (parent instanceof MyGridView) { if (((MyGridView)parent).isOnMeasure) { return convertView; } } String url = (String)getItem(position); HttpUtil.loadImage(context, Stringutil.get208x312(url), vh.iv); vh.iv.setOnClickListener(new MyClickListener(Stringutil.get480x800(url))); num++; Log.i("Cat", "getView() : Main = "+num+""); return convertView; }
這樣就能完全解決屢次調用問題