2

I have a header view in a ListView I want to hide when not in use. I've included code that sets its visibility to View.GONE or View.VISIBLE depending on another control.

Unfortunately, the view I am trying to show and hide is laying out as though I were setting its visibility to View.INVISIBLE—that is, the ListView is allowing space for it even when it's hidden. How can I prevent this?

I have tried calling requestLayout() and it hasn't had any effect.

I am going to try one of the suggested solutions here:

Hide footer view in ListView?

namely, wrapping my header in a FrameLayout and letting the FrameLayout handle the layout change, not the ListView.

EDIT: I have found that basically the same bug occurs when I added a ViewPager subclass in which I had overridden onMeasure(int widthMeasureSpec, int heightMeasureSpec) as a header view: it was designed to lay itself out again when children were added, but the ListView displayed it wrongly. As a child of a LinearLayout, however, this worked fine.

Community
  • 1
  • 1
Andrew Wyld
  • 7,133
  • 7
  • 54
  • 96

3 Answers3

6

I have added a FrameLayout as a parent view of the header tile I wish to hide. This means that when I hide the tile, the FrameLayout shrinks to fit it, and reports a height of zero to the ListView, which also shrinks. This is a pretty effective workaround, though a little weird.

Andrew Wyld
  • 7,133
  • 7
  • 54
  • 96
  • Using this method, it causes issues to the SwipeRefreshLayout (allows to swipe-to-refresh before the header is completely shown). How can I fix that? – android developer Aug 31 '15 at 08:00
0

Don't use View.VISIBLE or View.GONE for Showing and Hiding ListView Header and Footer.

Go Through removeHeaderView for help.

View v="YOUR VIEW";//Assume

You can remove Header like

your_list.removeHeaderView(v)

And you can add

your_list.addHeaderView(v);

Hope this help you.

Amit Gupta
  • 8,914
  • 1
  • 25
  • 33
  • As I understand headers have to be fixed before you set the adapter so `ListView` can wrap the cursor, so I'm not sure this would help? http://developer.android.com/reference/android/widget/ListView.html#addHeaderView(android.view.View) – Andrew Wyld Oct 29 '13 at 11:31
  • @amit gupta but why we should not use View.GONE – Bharat Sharma Oct 29 '13 at 11:35
  • @BharatSharma there is a method removeHeaderView(View) in ListView, so why not use this method instead of View.GONE? – Amit Gupta Oct 29 '13 at 11:38
  • Also this doesn't account for the situation where there are many header views: when you re-add the header view it will not appear in its original position. In general this solution wouldn't work with a `ListView` with an attached adapter either, and a better solution if an adapter wasn't required would be a `LinearLayout` in a `ScrollView`. – Andrew Wyld Oct 29 '13 at 11:38
  • @AmitGupta because this will mess with the way `ListView` wraps the adapter cursor, and doesn't let you re-add the header in the correct position. I want to hide *and* show the header. – Andrew Wyld Oct 29 '13 at 11:39
  • @AndrewWyld so better add a layout above to ListView, don't use addHeaderView(). – Amit Gupta Oct 29 '13 at 11:41
  • @AmitGupta Then the layout above won't scroll with the list. – Andrew Wyld Oct 29 '13 at 11:43
  • @AndrewWyld in this scenario don't use ListView, better use ScrollView and add the data(List item) dynamically. – Amit Gupta Oct 29 '13 at 11:49
  • @AmitGupta ... but this is what `ListView` is *for*. Seriously, writing a complete `AdapterView` implementation just to work around a layout bug in `ListView` (if that's what this is) seems like massive overkill. I don't think this solution is particularly helpful or relevant, but thank you for your suggestions. Also your original post would actually violate the way `ListView` is supposed to handle the adapter (see the doc link I posted) so I think it's misleading. – Andrew Wyld Oct 29 '13 at 11:52
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/40179/discussion-between-andrew-wyld-and-amit-gupta) – Andrew Wyld Oct 29 '13 at 11:59
0

That was my original code which was not working:

wv = new WebView(getActivity());
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
wv.setLayoutParams(params);
...

((ListView) mainListView).addHeaderView(wv);

I have placed my webview to framelayout and added this framelayout to listview with addHeaderView

FrameLayout fl = new FrameLayout(getActivity());
AbsListView.LayoutParams paramsFl = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
fl.setLayoutParams(paramsFl);

wv = new WebView(getActivity());
AbsListView.LayoutParams params = new AbsListView.LayoutParams(AbsListView.LayoutParams.MATCH_PARENT, AbsListView.LayoutParams.WRAP_CONTENT);
wv.setLayoutParams(params);
...

fl.addView(wv);

((ListView) mainListView).addHeaderView(fl);

after that when I set visibility of my webview to GONE header became not visible.

Talanted Vu
  • 21
  • 1
  • 5