Android 4.4以下ListView addHeader和addFooter放在setAdapter之后导致异常的原因分析和解决
2016-12-08 13:17
447 查看
问题重现:
在Android 19之前,ListView的addHeader和addFooter必须在setAdapter之前调用,否则就会有异常,Android 19以及之后是没有这个问题的。异常的具体表现为:1.在setAdapter之后调用mListView.addHeaderView(mHeader);会抛出异常:
Cannot add header view to list -- setAdapter has already been called.
2.在setAdapter之后调用mListView.addFooterView(mFooter);虽然不会抛出异常,但是却看不到添加的footer。
问题解决:
在Android 19之前,如果想在setAdapter之后添加header和footer,可以这样做://设置adapter之后设置header和footer ListAdapter originalAdapter; //得到之前给listview设置的adapter,如果已经知道,可以不用 if (mListView.getAdapter() instanceof HeaderViewListAdapter) { HeaderViewListAdapter headerViewListAdapter = (HeaderViewListAdapter) mListView.getAdapter(); originalAdapter = headerViewListAdapter.getWrappedAdapter(); } else { originalAdapter = mListView.getAdapter(); } mListView.setAdapter(null); mListView.addHeaderView(mHeader); mListView.addFooterView(mFooter); mListView.setAdapter(originalAdapter);
问题原因
我们可以对比Android 18和19的ListView的源码,在addHeaderView的改变:API 18
public void addHeaderView(View v, Object data, boolean isSelectable) { if (mAdapter != null && ! (mAdapter instanceof HeaderViewListAdapter)) { throw new IllegalStateException( "Cannot add header view to list -- setAdapter has already been called."); } FixedViewInfo info = new FixedViewInfo(); info.view = v; info.data = data; info.isSelectable = isSelectable; mHeaderViewInfos.add(info); // in the case of re-adding a header view, or adding one later on, // we need to notify the observer if (mAdapter != null && mDataSetObserver != null) { mDataSetObserver.onChanged(); } }
API 19
public void addHeaderView(View v, Object data, boolean isSelectable) { final FixedViewInfo info = new FixedViewInfo(); info.view = v; info.data = data; info.isSelectable = isSelectable; mHeaderViewInfos.add(info); // Wrap the adapter if it wasn't already wrapped. if (mAdapter != null) { if (!(mAdapter instanceof HeaderViewListAdapter)) { mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter); } // In the case of re-adding a header view, or adding one later on, // we need to notify the observer. if (mDataSetObserver != null) { mDataSetObserver.onChanged(); } } }
可以看到,在Android 19之前,如果ListView设置过Adapter,会抛出异常,在Android 19中,google做了调整。
相关文章推荐
- 【android】从源码上分析ListView/GridView调用setEmptyView不起作用的原因及解决办法
- 【android】从源码上分析ListView/GridView调用setEmptyView不起作用的原因及解决办法
- ListView的Adapter在getView()的时候position始终为0,异常解决了,求解答根本原因
- oid android.widget.ListView.setAdapter(android.widget.ListAdapter)' on a null object reference的解决
- Android Force Close 出现的异常原因分析及解决方法
- Android Listview addHeaderView setadapter的时候莫名NullPointerException 解决
- 从源码上分析ListView/GridView调用setEmptyView不起作用的原因及解决办法
- Android ListView setOnItemClickListener点击无效原因分析
- Android ListView异步载入图片乱序问题,原因分析及解决方式
- 解决adapter.getView()方法多次被调用,导致listView卡顿的原因。
- listView的item中有checkbox,导致setOnItemClick失效的原因及解决办法
- 【Android】 解决listview和BaseAdapter配合因加入button导致整个item点击失效
- Android 解决bug:异常提示"ListView cannot be cast to android.widget.BaseAdapter "
- Android JNI调用OpenCV,长时间运行内存异常,导致闪退的log分析和解决---(ReferenceTable overflow (max=1024)造成的)
- Android中EditText+Button组合导致输入板无法收起的原因分析及解决办法
- Android:ListView、ListActivity、 setListAdapter
- Android ListView BaseAdapter 分析
- android listview 连续调用 getview问题分析及解决。
- android listview 中加 button、imagebutton等之后失去点击效果的解决办法
- android,AnimationDrawable 在ListView里不动的分析及解决办法。