只要先addHeadView再setAdapter即可解决。
下面简单探究一下
Demo实例
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ListView lv = new ListView(this);
setContentView(lv);
// TextView headView = new TextView(this);
// headView.setText("headView");
// lv.addHeaderView(headView);
List<String> dataList = new ArrayList<String>();
for (int j = 0; j < 30; j++) {
dataList.add("" + j);
}
ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String>(
this, android.R.layout.simple_list_item_1,
dataList);
lv.setAdapter(arrayAdapter);
TextView headView = new TextView(this);
headView.setText("headView");
lv.addHeaderView(headView);
}
}
修改代码,只要在setAdapter之前addHeaderView就ok了。
源码分析
注意这里要使用低版本的sdk的源代码进行分析(这里使用Android4.0)
public void addHeaderView(View v) {
addHeaderView(v, null, true);
}
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.");
}
...
HeaderViewListAdapter这是怎么来的呢?让咱们看一下setAdapter
@Override
public void setAdapter(ListAdapter adapter) {
...
if (mHeaderViewInfos.size() > 0|| mFooterViewInfos.size() > 0) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, adapter);
...
mHeaderViewInfos是什么?和headView有关系?让咱们继续看一下addHeadView
public void addHeaderView(View v) {
addHeaderView(v, null, true);
}
public void addHeaderView(View v, Object data, boolean isSelectable) {
...
FixedViewInfo info = new FixedViewInfo();
info.view = v;
info.data = data;
info.isSelectable = isSelectable;
mHeaderViewInfos.add(info);
...
看到了mHeaderViewInfos包含了headView的容器的列表,mHeaderViewInfos反应了ListView中headView的信息。
所以:在低版本sdk中,从代码级别就限制ListView必须要先addHeadView,然后setAdapter.
让咱们看一下高版本的情况吧(这里使用Android6.0)
public void addHeaderView(View v) {
addHeaderView(v, null, true);
}
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);
mAreAllItemsSelectable &= isSelectable;
// Wrap the adapter if it wasn't already wrapped.
if (mAdapter != null) {
if (!(mAdapter instanceof HeaderViewListAdapter)) {
mAdapter = new HeaderViewListAdapter(mHeaderViewInfos, mFooterViewInfos, mAdapter);
}
...
版本升级了,的确是更好了!
为了兼容低版本,我们依然要首先addHeadView,然后setAdapter.