21

Trying to use addHeaderView() and addFooterView() for a ListView. If I try to use a View that I've predefined in XML for either the header or footer, I get a null pointer exception. However, if I dynamically create a View using code, it works fine...

// This doesn't work... nullPointerException
ListView lv = (ListView) findViewById(R.id.my_list_view);
TextView header = (TextView) findViewById(R.id.my_header);
lv.addHeaderView(header);

// This works fine
ListView lv = (ListView) findViewById(R.id.my_list_view);
TextView header = new TextView(this);
TextView.setHeight(30);
TextView.setText("my header text!");
lv.addHeaderView(header);

My stack trace:

Caused by: java.lang.NullPointerException
    at android.widget.ListView.clearRecycledState(ListView.java:522)
    at android.widget.ListView.resetList(ListView.java:508)
    at android.widget.ListView.setAdapter(ListView.java:440)
    at com.company.myapp.MyActivity.refreshList(MyActivity.java:85)
    at com.company.myapp.MyActivity.onCreate(MyActivity.java:37)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    ... 11 more

Any clues?

Dexter
  • 4,036
  • 3
  • 47
  • 55
Jake Wilson
  • 88,616
  • 93
  • 252
  • 370

1 Answers1

101

EDIT:

you simply cannot do

View header = findViewById(R.layout.headerView);
lst.addHeaderView(header);

This will NOT work because the view which is being passed in has to be inflated. In a nutshell when you do setContentView at the beginning of your activity the android framework automatically inflates the view and puts it to use. In order to inflate your header view, all you have to do is

View header = (View)getLayoutInflater().inflate(R.layout.headerView,null);
ls.addHeaderView(header);

lastly, add your adapter after you’ve set the header view and run the application. You should see your header view with the content you put into your adapter.

In my case, this works

View header = getLayoutInflater().inflate(R.layout.header, null); 
View footer = getLayoutInflater().inflate(R.layout.footer, null); 

ListView listView = getListView();  

listView.addHeaderView(header); 
listView.addFooterView(footer);     

setListAdapter(new ArrayAdapter<String(this,android.R.layout.simple_list_item_single_choice,android.R.id.text1, names)); 
user370305
  • 108,599
  • 23
  • 164
  • 151
  • That appears to work. Really strange that it works fine with dynamically created elements. Not sure why I have to jump through the layout inflater hoop here. Also, this method appears to ignore any margins I have set in my View's xml... – Jake Wilson Oct 20 '11 at 16:26
  • can you try to put that textview in different layout then inflate it and after use to set header and footer view? – user370305 Oct 20 '11 at 16:29
  • 1
    That worked. I just wrapped my `TextView` in a `LinearLayout`. I'll mark this as my answer, but I wish I knew why I had to jump through the hoops to make it work. Can't tell if it's a bug or what. Thanks! – Jake Wilson Oct 20 '11 at 16:37