[Android] IllegalStateException: Cannot add header view to list : setAdapter has already been called.

Tue, June 25, 2013 - 2 min read

Android アプリ開発にて、ListFragment で setListAdapter した後に addHeaderView や addFooterView を呼び出すと java.lang.IllegalStateException 例外が発生して、アプリがクラッシュしてしまいます。

Android 4 系だと例外は発生しなくて、Android 2.3 系だと例外でクラッシュするみたいです。

Stack Trace
_________________________________
0  java.lang.RuntimeException: Unable to resume activity {com.example/com.example.activity.MainActivity}:
 java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.
1    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2124)
2    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
3    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
4    at android.os.Handler.dispatchMessage(Handler.java:99)
5    at android.os.Looper.loop(Looper.java:123)
6    at android.app.ActivityThread.main(ActivityThread.java:3691)
7    at java.lang.reflect.Method.invokeNative(Native Method)
8    at java.lang.reflect.Method.invoke(Method.java:507)
9    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
10    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
11    at dalvik.system.NativeStart.main(Native Method)
12  Caused by: java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.
13    at android.widget.ListView.addHeaderView(ListView.java:336)
14    at android.widget.ListView.addHeaderView(ListView.java:359)
15    at com.example.fragment.NewFragment.refreshListView(NewFragment.java:358)
16    at com.example.fragment.NewFragment.onResume(NewFragment.java:143)
17    at android.support.v4.app.Fragment.performResume(Fragment.java:1503)
18    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
19    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
20    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
21    at android.support.v4.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:1871)
22    at android.support.v4.app.FragmentActivity.onResumeFragments(FragmentActivity.java:455)
23    at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:444)
24    at com.actionbarsherlock.app.SherlockFragmentActivity.onPostResume(SherlockFragmentActivity.java:69)
25    at android.app.Activity.performResume(Activity.java:3867)
26    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2114)
27    ... 10 more
28  java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.
29    at android.widget.ListView.addHeaderView(ListView.java:336)
30    at android.widget.ListView.addHeaderView(ListView.java:359)
31    at com.example.fragment.NewFragment.refreshListView(NewFragment.java:358)
32    at com.example.fragment.NewFragment.onResume(NewFragment.java:143)
33    at android.support.v4.app.Fragment.performResume(Fragment.java:1503)
34    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:947)
35    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
36    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1070)
37    at android.support.v4.app.FragmentManagerImpl.dispatchResume(FragmentManager.java:1871)
38    at android.support.v4.app.FragmentActivity.onResumeFragments(FragmentActivity.java:455)
39    at android.support.v4.app.FragmentActivity.onPostResume(FragmentActivity.java:444)
40    at com.actionbarsherlock.app.SherlockFragmentActivity.onPostResume(SherlockFragmentActivity.java:69)
41    at android.app.Activity.performResume(Activity.java:3867)
42    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2114)
43    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2139)
44    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:961)
45    at android.os.Handler.dispatchMessage(Handler.java:99)
46    at android.os.Looper.loop(Looper.java:123)
47    at android.app.ActivityThread.main(ActivityThread.java:3691)
48    at java.lang.reflect.Method.invokeNative(Native Method)
49    at java.lang.reflect.Method.invoke(Method.java:507)
50    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:864)
51    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:622)
52    at dalvik.system.NativeStart.main(Native Method)

正しいコード

// addHeaderView 後に setListAdapter
listView.addHeaderView(headerView);
listView.addFooterView(footerView);

setListAdapter(arrayAdapter);

IllegalStateException でクラッシュするコード

// setListAdapter 後に addHeaderView
setListAdapter(arrayAdapter);

listView.addHeaderView(headerView);
listView.addFooterView(footerView);

必ず setListAdapter する前に、addHeaderView や addFooterView を呼び出すようにしましょう。

[参考]

Note to self: ListFragment and header views

android - ListFragment add headerView gives java.lang.IllegalStateException:alled - Stack Overflow

Android - ListActivity, add Header and Footer view - Stack Overflow

android - How to add footer view dynamically - Stack Overflow