ListView inside ViewPager inside ScrollView - android

I am currently developing an Android app based on an iOS version, and I have to implement the following layout for the main menu:
a top hub with a few buttons, and then a ViewPager under it. This ViewPager has a bar over it (between itself and the hub) to display pages' titles. Inside the ViewPager is a ListView to display articles.
The expected scrolling behaviour is the following: When you scroll down from the very top, it should scroll normally and hide the hub, and then when you have scrolled enough to where the title bar reaches the top it should snap the title bar in place and you should still be able to scroll the ListView.
I have no idea how to add the hub to all of this and have the desired behaviour. Everything is already implemented and functions properly without the hub. But I have no idea how to add it and make it work.
I tried putting everything in a ScrollView, but this does not seem to work. The scrolling still works on the ListView of articles but it does not scroll the hub out of the way.
According to most people, you should never have a scrolling element inside another one. But I don't see any other way to do this.

I had multiple listviews inside a scrollview and to make it work I set the height of every list view using the following method. Things used to work fine.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(),
MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, listView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth,
LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}

I've implemented this component what works as a ListView, so you don't need to adapt your external code and it solves the problem with ListView inside Scrollview together with other elements...I named it StretchedListView, No external hacks required. It is in an answer to another post: https://stackoverflow.com/a/21878703
Enjoy!

Related

How to make a listview display all items without scrolliing?

I understand that putting a ListView inside a ScrollView is not recommmender. But I must use a ListView, simply because I'm using an adapter and various other methods.
I have used this code, which I found on StackOverflow and it shows me the majority of my list. However, in portrait mode some items are cut off from the bottom and in landscape mode the same.
How can this be rectified? To clarify, I've got a ScrollView containing a LinearLayout containing some elements and my ListView in my XML.
In addition, if I go to a new activity, then return I can briefly see the scroll bars for listview show up and disappear. How can this be rectified too?
public static boolean setListViewHeightBasedOnItems(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null) {
int numberOfItems = listAdapter.getCount();
// Get total height of all items.
int totalItemsHeight = 0;
for (int itemPos = 0; itemPos < numberOfItems; itemPos++) {
View item = listAdapter.getView(itemPos, null, listView);
item.measure(0, 0);
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
Use recycler-view or list-view and make use of view-type to inflate different layouts instead of using scroolview and nesting up other viewgroups inside.
I think your question is a bit misleading. How on earth can a listview displays its all items without scrolling as long as we are dealing with these tiny mobile screens?
Maybe you want that scroll bar to not show up, then you can set attribute like this on your ScrollView:
android:scrollbars="none"

android-ListView inside scrollView not working properly

I've to use listView inside a scrollView , for some reasons I can't use addHeader for addFooter .
When I set adapter to my listView , I change it heights but it's not working properly .
This is my code :
lv.setAdapter(ladap);
int totalHeight = 0;
for (int size = 0; size < ladap.getCount(); size++) {
View listItem = ladap.getView(size, null, lv);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = lv.getLayoutParams();
params.height = totalHeight + (lv.getDividerHeight() * (ladap.getCount() - 1));
lv.setLayoutParams(params);
lv.requestLayout();
This is the result :
as you can see, the listview is finished in the middle of the page but it still scrolls alot .
How to make it right ?
You don't need to use a ScrollView with a ListView. As stated in the Android Dev docs:
You should never use a ScrollView with a ListView, because ListView takes care of its own vertical scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by ScrollView.

Android: How to display first three items in listview and rest within scroll

Currently i am displaying listview using visibility "GONE" and then "VISIBLE" on button click, But its displaying only 1 item in listview, other elements in scrollview ( i need to scroll), so i decided to keep listview showing atleast 3 items first and rest element on listview scroll.
how to work out this, thanks in advance.
1st image is my code
i need to have like 2nd image
A ListView inside a ScrollView is a bad idea in general.
Instead you should use a LinearLayout and inflate your ListItems in there.
Not too hard to do. Just use a for loop or something.
If you MUST use a ListView you can call the following method on your ListView after it has been populated.
(change listAdapter.getCount() to the number of cells you want to show
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}

ScrollView show large space at bottom

I have added Button and ListView on a ScrollView. Button is added below to the ListView in ScrollView but Problem is that it shows large space between button and ListView. Here is my code
ReservationDrinkListAdapter adp = new ReservationDrinkListAdapter(this,
KukumberApplication.getInstance().getBottleService().menuItems);
list.setAdapter(adp);
Util.setListViewHeightBasedOnChildren(list);
following method is used to show ListView in ScrollView.
public static void setListViewHeightBasedOnChildren(ListView listView)
{
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
What am I doing wrong? Any Suggestion and sample code Would be appreciated.
Using a listview inside of a scrollview is technically possible but is not at all recommended, doing as you have (expanding the whole list so the scrollview accomodates all the list) goes against the whole point of adapterviews (performance) and will cause you lots of issues such as those you have encountered.
You can see more about this in answers such as:
How can I put a ListView into a ScrollView without it collapsing?
How to add two listview in scrollview
Why ListView cannot be used in a ScrollView?
ListView inside ScrollView is not scrolling on Android
And there are even more out there.

ListView contents get cutoff after Adapter update

I have a number of vertically stacked panels in my UI. Each panel contains a ListView. Based on user interaction, the number of items in the ListView gets updated.
My problem is that if I increase the number of items being shown in the ListView, the containing panel will not expand to show them. Instead, my ListView just gets cut off with a fade to black. I am programmatically creating each of these stacked panels - this is the body of the creating function:
LinearLayout containingPanel = new LinearLayout(TestActivity.this);
containingPanel.setOrientation(LinearLayout.VERTICAL);
// create title
TextView titleText = new TextView(TestActivity.this);
titleText.setText("a title");
titleText.setGravity(Gravity.CENTER);
titleText.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
// create dynamic list view of costs
ListView dynamicContentListView = new ListView(TestActivity.this);
dynamicContentListView.setAdapter(new MyDynamicAdapter());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params.weight = 1;
dynamicContentListView.setLayoutParams(params);
// build up GUI
containingPanel.addView(titleText);
containingPanel.addView(dynamicContentListView);
return containingPanel;
I thought that setting the weight on the ListView should be enough, but it is not. All GUI updating is working fine - new items are automatically added to data backing the Adapter, and the ListView updates itself properly. But after I add three or four new items, the containingPanel refuses to update itself and the new items get blended out.
try this function. I think, it might help you. The function is used to set ListView's height based on its children.
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
(You can add a ListView inside a ScrollView but not without a little work (as they are both Scrollable components - how would the OS know which one you're trying to scroll?). You would need to add isScrollContainer="false" on your ListView.)
<ListView
android:id="#+id/list"
android:layout_width="match_parent"
android:layout_height="wrap_contents"
android:isScrollContainer="false"/>
The entire point of a ListView is it has a set height as dictated by the layout of your page. It only becomes scrollable when it's children's combined height exceed the area required to display it.
It sounds like what you actually want is something more akin to a LinearLayout which is backed by an Adapter, there are several implementations out there on the web or you can create your own.
However, you can hack a ListView into this behaviour by dynamically resizing your ListView programatically by setting it's Height to: listCount * itemHeight. This would have the effect of consistently expanding your ListView.
You will likely find that as you develop your UI design you will no longer require such a component.
If your listview is a default size, it might not be able to fit them in the layout. You could try to wrap the listview in a scrollview and then you can scroll through them.

Categories

Resources