天天看點

解決:ScrollView中嵌套ListView,使得listview上下滑動卡頓現象

解決:ScrollView中嵌套ListView,使得listview上下滑動卡頓現象

效果圖就是上面的那樣!實作方式:上面是一個ViewPager實作的左右無限循環并帶有自動輪播的banner。在banner圖的下面是一個listview實作上拉加載的功能;但是在我實作的過程中我遇到了一個問題,就是整個頁面的展示效果都已經實作,但是banner圖連帶下面的listview在上下滑動的時候出現卡頓的現象;當然之前也遇到了一個問題,就是我的banner圖和listview一起放在了父控件ScrollView中,是的listview不能完全顯示;那麼就來解決這兩個問題。

解決問題一:<listview置放在ScrollView中不能完全顯示>

調用下面這個方法在listview.setAdapter();或者adapter.notifyDataSetChanged();之後,可以讓該不能完全顯示的listview正确的顯示在其父控件ScrollView中。但是要注意的是,對于listview中的每個Item的填充布局,布局的根必須是Linearlayout控件;否則,listview就不能通過onMeasure()正确的計算到每個Item的高度并顯示出來,并會抛出異常!要調用方法如下:抛出異常的展示如圖:

解決:ScrollView中嵌套ListView,使得listview上下滑動卡頓現象
/**
	 * 動态測量listview-Item的高度
	 * @param listView
	 */
	public static void setListViewHeightBasedOnChildren(ListView listView) {  
        ListAdapter listAdapter = listView.getAdapter();   
        if (listAdapter == null) {  
            // pre-condition  
            return;  
        }  
  
        int totalHeight = 0;  
        for (int i = 0; i < listAdapter.getCount(); i++) {  
            View listItem = listAdapter.getView(i, null, listView);  
            listItem.measure(0, 0);  
            totalHeight += listItem.getMeasuredHeight();  
        }  
  
        ViewGroup.LayoutParams params = listView.getLayoutParams();  
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));  
        listView.setLayoutParams(params);  
    }  
	
           

還有一種解決方式:不再重新計算listview高度,禁止滑動,直接加載顯示所有的Item資料:<重寫listview,重寫onMesure方法>

/**
    * 設定不滾動
    */
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
    int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
    MeasureSpec.AT_MOST);
    super.onMeasure(widthMeasureSpec, expandSpec);
    }
           

解決問題二:<listview上下滑動卡頓>

隻要是listview上下滑動卡頓,其主要原因是因為在listview填充擴充卡的時候。在重寫的類BaseAdapter方法getView();被無限的循環的調用;這樣消耗了大量的記憶體導緻listview上下滑動的時候,出現了卡頓。原因就在于measure過程,ListView一般都會根據螢幕加載多個Item,而且也會同時顯示這些已經加載過的若幹組Item,而這些Item的父元素都是這個ListView。

通過Google的解釋:View在Draw的時候分成兩個階段:measure和layout,在measure階段時主要就是為了計算兩個參數:height和width。而且要注意的是,這是個遞歸的過程,從頂向下,DecorView開始依次調用自己子元素的measure。計算完成這兩個參數後就開始layout,最後再是draw的調用。對于ListView,當然每一個Item都會被調用Measure方法,而在這個過程中getView和getCount會被調用,而且看使用者的需求,可能會有很多次調用。問題就在于在layout中的決定ListView或者它的父元素的height和width屬性的定義了。根據我的經驗,height和width最好都設定成fill_parent,這樣能避免listview對getView的瘋狂調用。解決方法就是盡量避免自适應,除非是萬不得已,固定大小或者填充的效果會比較好一些。還有一點請注意,如果使用了上面的動态測量來設定listview的顯示高度,并使用了fill_parent來設定了listview的屬性,但是仍然不能停止adapter中getView()方法的瘋狂調用;或者還伴有listview内容顯示仍然不完全現象;根據我自己的實踐經驗來講,你可以這樣做:把listview放置在LinearLayout中,<LinearLayout中隻存在一個listview>;我推斷是,當你通過動态測量加載的時候,ta需要一個獨立的空間。

如此下來,基本上就解決了,放在ScrollView中時候listview滑動卡頓,顯示不完全的現象。

 建一個群,友善大家交流:蹦蹦哒Android <群号:423923313>