I have an android layout which has a scrollView with a number of elements with in it. At the bottom of the scrollView I have a listView which is then populated by an adapter.
The problem that I am experiencing, is that android is excluding the listView from the scrollView as the scrollView already has a scroll-able function. I want the listView to be as long as the content is and for the master scroll view to be scroll-able.
i want to set the scrollView scroling if the listView has complete her scroling
#Gaurav Roy
You do not have to do anything special in layout.xml file nor handle anything on the parent ScrollView. You only have to handle the child ListView. You can also use this code to use any type of child view inside a ScrollView & perform Touch operations.
Just add these lines of code in your java class :
ListView lv = (ListView) findViewById(R.id.layout_lv);
lv.setOnTouchListener(new OnTouchListener() {
// Setting on Touch Listener for handling the touch inside ScrollView
#Override
public boolean onTouch(View v, MotionEvent event) {
// Disallow the touch request for parent scroll on touch of child view
v.getParent().requestDisallowInterceptTouchEvent(true);
return false;
}
});
If you put ListView inside a ScrollView then all the ListView does not stretch to its full height. Below is a method to fix this issue.
/**** Method for Setting the Height of the ListView dynamically.
**** Hack to fix the issue of not showing all the items of the ListView
**** when placed inside a ScrollView ****/
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);
}
To use this method just pass the ListView inside this method :
ListView list = (ListView) view.findViewById(R.id.ls);
setListViewHeightBasedOnChildren(list);
For using with ExpandableListView - credit Benny
ExpandableListView: view = listAdapter.getView(0, view, listView);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.MATCH_PARENT, View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(ViewGroup.LayoutParams.WRAP_CONTENT, View.MeasureSpec.EXACTLY);
view.measure(widthMeasureSpec, heightMeasureSpec);
For ListView with variable items height use the below link :
ListView inside ScrollView is not scrolling on Android
For Library to directly implementing in your code - credit Paolo Rotolo
https://github.com/PaoloRotolo/ExpandableHeightListView
Instead of embedding a ListView inside of a ScrollView, add the contents of the scrollview to a single viewgroup, then add those programatically to the top of the ListView with addHeaderView.
For instance, have the root element of your layout be a ListView, and inflate a separate layout with the rest of the views via a LayoutInflater. Then just pass that reference to the inflated view into the addHeaderView method.
Related
I have a RelativeLayout activity contains a list-view. I want to make the list-view height based on its items, I searched in the internet and found many methods do this but all methods give the list-view height greater than items height.
The method I use as following:
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),
View.MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
when I debug the method If found that there are some items height equal to "45" and some items height equal to "66" while all items in the list-view have the same height when the activity appear.
Here is a snapshot of the activity, the list-view background is light-gray to show the list-view height:
Activity snpapshot
if you want the whole list to be visible then don't use list view
listview is not made for this it's made to fill the screen and the reusing it's views
use a scrollview with linear and inflate them inside but the is a bad approach and will take a long time
so please revisit the reasons you are doing this maybe you will find a better Widget for it or maybe share a screenshot of the ui you are trying to achieve
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!
I'm aware that there's been a lot Q&A on this topic, but i still didn't find the right answer.
I want my ListView (inside of a ScrollView) to 'expand' over the bottom edge of the screen to show all of the items without need for scrollbar therefore it wouldn't be a problem to put ListView inside ScrollView and we would be able to scroll whole activity.
Puting items collection in LinearLayout is not a solution - it's just to damn slow. It takes 2-3 sec to draw 100 items while ListView does it instantly.
You could set the ListView's layout_height to wrap_content, but then it would be as slow as the LinearLayout. The whole point of ListView is that its content is fake; it only creates the rows that are visible within its height. Making it as tall as its content would take away its advantage.
I'd suggest re-thinking what you're trying to do. Perhaps you can put all of your widgets inside the ListView and then you wouldn't need a ScrollView.
You can try set Listview's height at runtime by using this snippet
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);
if (listItem instanceof ViewGroup)
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
}
And example to use this
listComment.setAdapter(new CommentAdapter(comment,
AppDetailActivity.this));
listComment.postDelayed(new Runnable() {
#Override
public void run() {
// TODO Auto-generated method stub
Utils.setListViewHeightBasedOnChildren(listComment);
}
}, 500);
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);
}
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.