Android: How to measure total height of ListView
Finally I've done it! This is the working code which measures ListView height and sets ListView in full size:
public static void getTotalHeightofListView(ListView listView) {
ListAdapter mAdapter = listView.getAdapter();
int totalHeight = 0;
for (int i = 0; i < mAdapter.getCount(); i++) {
View mView = mAdapter.getView(i, null, listView);
mView.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
totalHeight += mView.getMeasuredHeight();
Log.w("HEIGHT" + i, String.valueOf(totalHeight));
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight
+ (listView.getDividerHeight() * (mAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Android Listview Measure Height
Ok looks like I was able to figure out why the measurement was inaccurate. I was trying to get a measurement of the listview's height by passing
listItem.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
For ListItem's with variable/dynamic height, this will not work out. The measurement has to know at least one variable and in this case it will be the constant width. So, first calculate the desired width of the listview which you know is going to be constant, by using:
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
and then pass it to the listitem measure. Full code is given below:
public void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = listView.getPaddingTop() + listView.getPaddingBottom();
int desiredWidth = MeasureSpec.makeMeasureSpec(listView.getWidth(), MeasureSpec.AT_MOST);
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, listView);
if(listItem != null){
// This next line is needed before you call measure or else you won't get measured height at all. The listitem needs to be drawn first to know the height.
listItem.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
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();
}
Please Note This is a hackish implementation and isn't the recommended way. Please see How can I put a ListView into a ScrollView without it collapsing? and understand exactly what you are doing before implementing this.
How to calculate total row heights of listView in android?
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
The core of the function is these three lines, it try to measure each view. The 0 in listItem.measure(0, 0) is equals to MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED)
Mostly it will calculate the accurate height of the listview. There is one exception, when the view content is too much and will wrap line, i.e. there are to many lines of text. In such situation, you should specified a accurate widthSpec to measure(). So change listItem.measure(0, 0)
to
// try to give a estimated width of listview
int listViewWidth = screenWidth - leftPadding - rightPadding;
int widthSpec = MeasureSpec.makeMeasureSpec(listViewWidth, MeasureSpec.AT_MOST);
listItem.measure(listViewWidth, 0)
UPDATE about the formula here
int listViewWidth = screenWidth - leftPadding - rightPadding;
It's just an example to show how you can estimate the width of the width of listview, the formula is based on the fact that width of listview ≈ width of screen
. The padding is set by your self, maybe 0 here. This page tells how to get screen width.
In general, it's just a sample, and you can write your own formula here.
Related Topics
How to Calculate Azimuth, Pitch, Orientation When My Android Device Isn't Flat
What Happens If a Android Service Is Started Multiple Times
How to Change the Generated Filename for App Bundles with Gradle
How to Enable and Disable a Component
How Do Cursorloader Automatically Updates the View Even If the App Is Inactive
Android Device Is Not Connected to Usb for Debugging (Android Studio)
Android 4.4 Giving Err_Cache_Miss Error in Onreceivederror for Webview Back
Picasso Load Drawable Resources from Their Uri
Failed to Read Png Signature: File Does Not Start with Png Signature
How to Use Unicode in Android Resource
How to Load Class Androidcomponentsextension After Upgrading the Android Gradle Plugin 7.1
How to Detect When the User Launches Another App? (Android)
Inflate a View in a Background Thread
How to Programmatically Scroll Android Webview
Android Sharedpreferences , How to Save a Simple Int Variable