14

In my ListActivity, I need header and footer views (on the top and bottom of the list) to be used as previous page and next page buttons on my list, respectively, because I want to display only 20 items at a time.

I set my header and foot views by doing:

getListView().addHeaderView(myHeaderView);
getListView().addFooterView(myFooterView);
setListAdapter(adapter);

This works fine, but I need to dynamically remove and add these header and footer views, because some pages of my list may not have a next page button or a previous page button.

The problem is, I cannot call addHeaderView or addFooterView after I have called setListAdapter.

Is there a way around this?

Dan Lew
  • 85,990
  • 32
  • 182
  • 176
jlim
  • 801
  • 2
  • 13
  • 21

3 Answers3

10

Why not just collapse the header and footer to zero height, or gray out the buttons (even better).

And the best user experience, in my opinion, would be to dynamically load more items when needed (i.e. upon scroll), like the built-in Gmail app does.

Roman Nurik
  • 29,665
  • 7
  • 84
  • 82
  • 4
    Agreed on the dynamic-loading approach. I even created some reusable code to assist with this: http://github.com/commonsguy/cwac-endless – CommonsWare Jan 07 '10 at 01:49
  • 3
    If I remember correctly, the `ListView` doesn't re-layout the header or footer views, even if you set their visibility to `INVISIBLE` or `GONE`, so you're left with a big blank space. – Christopher Orr Jan 07 '10 at 01:49
  • At any rate, hiding them would be jarring; disabling sounds better. And Mark's (commonsware.com) approach is probably best. – Roman Nurik Jan 07 '10 at 02:09
  • 1
    I can only second Mark. There is also a ListAdapterWithProgress in the Droid-Fu library. You can use it to trigger a loading spinner as the last element e.g. when the user scrolls all the way down to the bottom. http://kaeppler.github.com/droid-fu/ – mxk Jan 07 '10 at 08:37
  • 1
    thanks for the replies, i'll give the zero height suggestion a shot :) @Christopher: yeah, setting visibility to GONE was my initial idea, but too bad there's that blank space – jlim Jan 07 '10 at 17:49
  • 1
    The only working easy way I found to hide an header is this: http://stackoverflow.com/questions/6829126/hiding-the-header-view-in-listview/7764524#7764524 – Rainbowbreeze Oct 27 '11 at 15:54
  • @RomanNurik-Google Setting the height to zero didn't work, instead, I used... `1` :-) –  May 06 '12 at 20:11
3

Yes, this is a bug or oversight in the ListView component. You can work around this by writing your own WrapperListAdapter that handles adding and removing fixed list items, but I can tell you it's not entirely straightforward to do.

Alternatively — and much easier — you could add a fixed component above or below the ListView where you place the next and previous buttons.

Christopher Orr
  • 110,418
  • 27
  • 198
  • 193
  • 1
    As an update, as Romain Guy mentions, this is the intended behaviour. I asked at Android "office hours" why this is the case. From what I recall, it's because the header and footers are taken into account as list items once the list is bound to a cursor, so adding/removing them would mess up the offsets. If you want to make a change you can rebind the adapter to the list. It would be nice if there was a wrapper that could handle this in the SDK, but it's definitely possible to create your own anyway. – Christopher Orr Jan 09 '10 at 22:44
2

How about reset the adapter at every time you need to add header view, like this way:

ListView.FixedViewInfo headerInfo = getListView().new FixedViewInfo();
headerInfo.isSelectable=false ;
headerInfo.view = feedInfoView;
headerInfos.add(headerInfo);
headerViewListAdapter = new HeaderViewListAdapter(headerInfos,null,adapter);
getListView().setAdapter(headerViewListAdapter);
Jammy Lee
  • 1,496
  • 1
  • 14
  • 32