20

I have one edittext field and one "search" button. When I click on search, I have to display a list view with data corresponding to the values entered in the edittext. I have added a header to my list using addHeader(). When I do search first time, I am able to display data in List successfully. But when I do search again, I am getting the below error.

FATAL EXCEPTION: main
java.lang.IllegalStateException: Cannot add header view to list -- setAdapter has already been called.
at android.widget.ListView.addHeaderView(ListView.java:261)
at android.widget.ListView.addHeaderView(ListView.java:284)

I have assigned header to my list before setting the adapter.

Below is my code:

myList = (ListView) findViewById(R.id.searchResultsList);
View header = View.inflate(this, R.layout.search_results_header, null);
myList.addHeaderView(header, null, false);

dataAdapter = new MyCustomAdapter(this, R.layout.results_list_item, searchedResults);
myList.setAdapter(dataAdapter);

Where I am doing wrong?

Hariharan
  • 24,741
  • 6
  • 50
  • 54
user2740599
  • 449
  • 4
  • 10
  • 20
  • Try to use dataAdapter.notifyDataSetChanged(); after setting adapter. – Android Killer Oct 25 '13 at 07:45
  • Have you checked this [Answer given by Hiren Patel][1]. It will help you. [1]: http://stackoverflow.com/questions/13217386/add-a-header-to-a-gridview-android/27290310#27290310 – Hiren Patel Dec 04 '14 at 09:27
  • Before 4.4, adapter should be set before calling addHeaderView method. You can check the difference between 4.4 and 4.3 source code: http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.4_r1/android/widget/ListView.java/?v=diff&id2=4.3.1_r1 – Faruk Toptas Feb 15 '16 at 10:52

10 Answers10

25

On android 2.3, add header after setAdapter (even if you have added early, then removed) will throw an exception. To hide or show a header dynamically, use setVisibility(). How? You can see Hiding header views.

ishitcno1
  • 713
  • 9
  • 10
12

Cannot add header view to list -- setAdapter has already been called. which you can see, the myList.addHeaderView(header) must be execute before myList.setAdapter(adapter);

user2919006
  • 129
  • 2
1

Try this..

dataAdapter = new MyCustomAdapter(this, R.layout.results_list_item, searchedResults);
myList.addHeaderView(header);
myList.setAdapter(dataAdapter);
dataAdapter.notifyDataSetChanged();
Hariharan
  • 24,741
  • 6
  • 50
  • 54
1

you can add FrameLayout as header view before setting adapter and dynamically add/remove view in FrameLaypout

Dmitry
  • 211
  • 1
  • 3
1

I had the same problem today. I have multiple ListViews.. With the information from the first, it builds the list of the next one and everyone has setAdapter in it. For me, the best solution was to put

setListAdapter(null);

on top of the function, where I inflate the Header. I hope this helps..

0x52
  • 883
  • 1
  • 11
  • 17
1

If you were used android:entries in ListView in xml file, Its called setAdapter() method before addHeaderView. So remove android:entriesattribute from ListView in xml layout file. It will be work.

AvisSiva
  • 707
  • 1
  • 9
  • 17
1

The exception is thrown by android api.For API Level below KITKAT the addHeader() or the addFooter() method must be called before setAdapter() method.

It is mentioned in the api documentation:

Note: When first introduced, this method could only be called before setting the adapter with setAdapter(ListAdapter). Starting with Build.VERSION_CODES.KITKAT, this method may be called at any time. If the ListView's adapter does not extend HeaderViewListAdapter, it will be wrapped with a supporting instance of WrapperListAdapter.

Manmohan Soni
  • 6,472
  • 2
  • 23
  • 29
0

After I set

final ViewGroup header = (ViewGroup) inflater.inflate(R.layout.item, listView, false);
listView.addHeaderView(header, null, true); 

before

listView.setAdapter(adapter);

a problem still appeared. Then I made Build > Clean Project.

CoolMind
  • 26,736
  • 15
  • 188
  • 224
-1

After so much efforts i got solution for my side i hope this will helps someone too

i already set adpater at the last (after view added) but dont know why i was suffring from same error so here i did something like this code

// Set View here
View view = getLayoutInflater().inflate(R.layout.navigation_header,null);
mDrawerList.addHeaderView(view);
// init your adapter
adapter1 = new YourListAdapter(getApplicationContext(),blabla);
// set adapter into handler
Handler handler = new Handler();
handler.postDelayed(new Runnable() {        
   @Override
  public void run() {
  // TODO Auto-generated method stub
  mDrawerList.setAdapter(adapter1);
  }
}, 100);

I put my adapter in to handler sometime it happends that adapter set faster then view so this code enough for me to solve this exception. :)

Kishan Soni
  • 816
  • 1
  • 6
  • 19
-2

I have used the following code in my sample application to set a ListView header:

ListView lv = getListView();
View headerView = getLayoutInflater().inflate(R.layout.layout_header, null, false);
lv.addHeaderView(headerView);
final TumblrDB db = new TumblrDB(this);
c = db.query();
startManagingCursor(c);
adapter = new CustomCursorAdapter(this, R.layout.layout_del, c, new String[]{TumblrDB.DATE, TumblrDB.DESC}, new int[]{R.id.txt_a, R.id.txt_b});
lv.setAdapter(adapter);
bra_racing
  • 622
  • 1
  • 8
  • 32
vamsiampolu
  • 6,328
  • 19
  • 82
  • 183