劇情是這樣的:
1 public class SomeViewGroup extends FrameLayout { 2 3 ... 4 5 public void setOnLoadMoreListener(OnLoadMoreListener onLoadMoreListener) { 6 7 mOnLoadMoreListener = onLoadMoreListener; 8 9 LayoutInflater mInflater = (LayoutInflater) getContext() 10 .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 11 loadMoreLayout = (ViewGroup) mInflater.inflate( 12 R.layout.list_load_more_layout, this); 13 loadMoreLayout.setOnClickListener(loadMoreClickListener); 14 loadMoreText = (TextView) loadMoreLayout 15 .findViewById(R.id.load_more_textview); 16 moreProgressBar = (ProgressBar) loadMoreLayout 17 .findViewById(R.id.load_more_progressbar); 18 loadMoreText.setVisibility(View.GONE); 19 mainList.addFooterView(loadMoreLayout); 20 21 } 22 23 ... 24 25 }
關鍵在紅色的那幾行,這個view在使用時會發生異常,
java.lang.ClassCastException: android.widget.FrameLayout$LayoutParams cannot be cast to android.widget.AbsListView$LayoutParams
下面來分析下原因和解決方法。
在ListView源碼里可以看到:
1 void resetList() { 2 // The parent's resetList() will remove all views from the layout so we need to 3 // cleanup the state of our footers and headers 4 clearRecycledState(mHeaderViewInfos); 5 clearRecycledState(mFooterViewInfos); 6 7 super.resetList(); 8 9 mLayoutMode = LAYOUT_NORMAL; 10 } 11 12 private void clearRecycledState(ArrayList<FixedViewInfo> infos) { 13 if (infos != null) { 14 final int count = infos.size(); 15 16 for (int i = 0; i < count; i++) { 17 final View child = infos.get(i).view; 18 final LayoutParams p = (LayoutParams) child.getLayoutParams(); 19 if (p != null) { 20 p.recycledHeaderFooter = false; 21 } 22 } 23 } 24 }
錯誤就是在第18行拋出的,這里的 mFooterViewInfos 實際上就是我們添加的Footer view的一個列表。代碼里循環處理每個footer view,而在getLayoutParams()時,ListView要求必須是AbsListView的LayoutParams,而在我們自己的代碼中:loadMoreLayout = (ViewGroup) mInflater.inflate(R.layout.list_load_more_layout, this),這里的this是FrameLayout,所以才拋出ClassCastException異常的。
解決方法很簡單,把我們自己代碼中的12行的this改成null就OK了:D
還有一點要注意,addFooterView()一定要在setAdapter()之前調用,否則,雖然不會像addHeaderView()那樣拋出異常,但是會導致footer view無法顯示。