關於ListView適配器getView()屢次執行

在使用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;
}

 

這樣就能完全解決屢次調用問題

相關文章
相關標籤/搜索