劇情是這樣的:
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無法顯示。