How to set Height of ListView.
XML Code (This code is working fine and fixed height as 200 dip)
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dip"
android:orientation="vertical" >
<ListView
android:id="#+id/dialog_ListView"
android:layout_width="wrap_content"
android:layout_height="200dip"
android:padding="5dip"
android:layout_weight="1"
android:dividerHeight="5dip"
android:divider="#android:color/transparent" />
</LinearLayout>
Android Code (This code not fixed width and height)
convertView = mInflater.inflate( R.layout.dialog_page, null );
convertView.setLayoutParams( new ListView.LayoutParams( 200, 300) );
Android Code (This code i got Error Message)
convertView = mInflater.inflate( R.layout.lock_file_page, parent );
convertView.setLayoutParams( new ListView.LayoutParams( 200, 300) );
Error Message
java.lang.UnsupportedOperationException: addView(View, LayoutParams) is not supported in AdapterView
How do fix Width and Height at Runtime.
Thanks in advance.
Try This code..
LayoutParams lp = (LayoutParams) mListView.getLayoutParams();
lp.height = 300;
mListView.setLayoutParams(lp);
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;
}
}
First Remove import files for LayoutParams and after that Use below code for LayoutParams.
LinearLayout.LayoutParams params=new LinearLayout.LayoutParams(200, 300);
convertView.setLayoutParams(params);
try this
public void setDynamicHeight(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
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){
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();}
Related
I'm working on a new application and i want to resize a ListView programmatically, for example from a ListView with params of 200x100 to a 100x100.
How can i resize the dimension of the ListView?
public void setListViewHeightBasedOnChildren(ListView listView) {
ArrayAdapter listAdapter = (ArrayAdapter) 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);
listView.requestLayout();
}
In my application i am using StaggeredGridView and it is working fine. But when i placed it inside a scorllview and try to scroll it unfortunately the height of the StaggeredGridView is not matching with the exact grid view.
For controlling the scroll i am dynamically caluculating the height of the gridview and setting it to the gridview programatically by Based On Children items. i think it will be the problem..
here the main problem is item heights will be not same like normal gridview.
Here is my code for setGridViewHeightBasedOnChildren
public static void setListViewHeightBasedOnChildren(StaggeredGridView listView) {
SampleAdapter listAdapter = (SampleAdapter) 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.getHeight() * (listAdapter.getCount() - 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Can any one help me out to placed a StaggeredGridView inside a scroll view..
Thanks in advance
Try to use below code with passing no of column :
public void setListViewHeightBasedOnChildren(StaggeredGridView staggeredGridView, int columns) {
SampleAdapter listAdapter = (SampleAdapter) staggeredGridView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int items = listAdapter.getCount();
int rows = 0;
View listItem = listAdapter.getView(0, null, staggeredGridView);
listItem.measure(0, 0);
totalHeight = listItem.getMeasuredHeight();
float x = 1;
if( items > columns ){
x = items/columns;
rows = (int) (x + 1);
totalHeight *= rows;
}
ViewGroup.LayoutParams params = gridView.getLayoutParams();
params.height = totalHeight;
gridView.setLayoutParams(params);
}
I have listView within scrollView (yes, I know thats bad approach. Better to use headers/footers). I know that scrollView and listView have both scroll and that causes some conflict. In this case I need to set height of list manually. And thats the problem since listView has custom adapter.
Layout:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/ScrollView01"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true"
android:scrollbars="none" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/fragment_lessons"
android:background="#FAF9F9"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.cbsystematic.mobile.itvdn.LessonsFragment">
<TextView
android:id="#+id/course_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Описание курса: "
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#000000"/>
<TextView
android:id="#+id/course_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="16sp"
android:layout_below="#id/course_title"
android:textColor="#000000"/>
<TextView
android:id="#+id/course_duration"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="14sp"
android:textStyle="italic"
android:layout_below="#id/course_description"
android:textColor="#000000"/>
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#id/course_duration"/>
</RelativeLayout>
</LinearLayout>
</ScrollView>
Custom List adapter:
class LessonsItemAdapter extends ArrayAdapter<LessonData> {
private Activity myContext;
private ArrayList<LessonData> datas;
public LessonsItemAdapter(Context context, int textViewResourceId, ArrayList<LessonData> objects){
super(context, textViewResourceId, objects);
myContext = (Activity) context;
datas = objects;
}
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder;
if(convertView == null) {
LayoutInflater inflater = myContext.getLayoutInflater();
convertView = inflater.inflate(R.layout.lessons_list_item, null);
viewHolder = new ViewHolder();
viewHolder.postNameView = (TextView) convertView.findViewById(R.id.lessons_name);
viewHolder.postDurationView = (TextView) convertView.findViewById(R.id.lessons_duration);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
//(position + 1) + ") " used to display 1) 2) 3) etc of lessons
viewHolder.postNameView.setText((position + 1) + ") " + datas.get(position).getName());
viewHolder.postDurationView.setText("Длительность: " + datas.get(position).getDuration().substring(0,8));
return convertView;
}
static class ViewHolder{
TextView postNameView;
TextView postDurationView;
}
}
Method of finding height:
public static void setListViewSize(AbsListView 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, AbsListView.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight + (listView.getMeasuredHeight() * (listAdapter.getCount() + 1));
listView.setLayoutParams(params);
listView.requestLayout();
}
Thats how I set the content of list:
mAdapter = new LessonsItemAdapter(getActivity(),
R.layout.lessons_list_item, parserJson.getLessons(courseUrl).getLessonsArray());
// Set the adapter
mListView = (AbsListView) view.findViewById(android.R.id.list);
((AdapterView<ListAdapter>) mListView).setAdapter(mAdapter);
// Set OnItemClickListener so we can be notified on item clicks
mListView.setOnItemClickListener(this);
ListHelper.setListViewSize(mListView);
And thats the result:
The entire View is scrolling. But the last item always shows only by half. You see, the field Duration ("Длительность") is not showing. Although the last item of list is clicakble.
Please help me with that method of defining the total height.
Thanks in advance. Appreciate any help.
Use this piece of code. It will reset the size of listview according to number of items.
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();
}
Your ListView in your layout file should be like
<ListView android:id="#android:id/list"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#id/course_duration"/>
Now in your code where you want the ListView's height to be adjusted according to its children place the following method.
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);
}
just call it by passing your ListView inside it
setListViewHeightBasedOnChildren(list);
Simple but powerful solution
try code below from this blog
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int newHeight = 0;
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (heightMode != MeasureSpec.EXACTLY)
{
ListAdapter listAdapter = getAdapter();
if (listAdapter != null && !listAdapter.isEmpty())
{
int listPosition = 0;
for (listPosition = 0; listPosition < listAdapter.getCount()
&& listPosition < MAXIMUM_LIST_ITEMS_VIEWABLE; listPosition++)
{
View listItem = listAdapter.getView(listPosition, null, this);
//now it will not throw a NPE if listItem is a ViewGroup instance
if (listItem instanceof ViewGroup)
{
listItem.setLayoutParams(new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
}
listItem.measure(widthMeasureSpec, heightMeasureSpec);
newHeight += listItem.getMeasuredHeight();
}
newHeight += getDividerHeight() * listPosition;
}
if ((heightMode == MeasureSpec.AT_MOST) && (newHeight > heightSize))
{
if (newHeight > heightSize)
{
newHeight = heightSize;
}
}
}
else
{
newHeight = getMeasuredHeight();
}
setMeasuredDimension(getMeasuredWidth(), newHeight);
}
We have an Android application with ListView, containing N items. For setting the height of ListView component, we use this method:
public static void setListViewHeightBasedOnChildren(ListView listView) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter == null) {
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();
}
The height is measured bad in the first run. If the method is called later (e.g. after reloading the ListView data becouse of change), the height is correct.
It seems that problem is in
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(), View.MeasureSpec.AT_MOST);
where the value desiredWidth is -2147483648 after first call, but -2147483368 after other calls and the height is set correctly.
Is there any way to change this behaviour and get the height correctly in the first call?
I need to change the height of a ListView dynamically in my app.
Is there any way to do that?
This piece of code helped me to achieve dynamic listview height.
import android.view.View;
import android.view.ViewGroup;
import android.view.View.MeasureSpec;
import android.widget.ListAdapter;
import android.widget.ListView;
public class Utility {
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();
}
}
In the main Activity use this Utility class to change the listview height.
phraseListView=(ListView)findViewById(R.id.phrase_listview);
phraseAdapter=new PhraseListAdapter(this);
phraseListView.setAdapter(phraseAdapter);
Utility.setListViewHeightBasedOnChildren(phraseListView);
Taken from here
for change height and width dynamically so, try this
RelativeLayout.LayoutParams mParam = new RelativeLayout.LayoutParams((int)(width),(int)(height);
listView.setLayoutParams(mParam);
you can also use LayoutParams.FILL_PARENT or LayoutParams.WRAP_CONTENT instead of height & width
You can use below method to set the height of listview programmatically as per your items:
<ListView
android:id="#+id/lvMenu"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
/>
Method used for setting height of listview:
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);
float px = 500 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
Then set it like below code:
MenuAdapter menuAdapter = new MenuAdapter(context, R.layout.menu_item);
lvMenu.setAdapter(menuAdapter);
setListViewHeightBasedOnItems(lvMenu);
Hope it will help you.
First thing to keep in mind is that while getting height of listview using mylistview.getmeasureheight, it always gives height according to the textview/View inside the list which was set during initializing of adapter. So we need to declare the adapter as follows:
myadapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,myarraylist){
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull ViewGroup parent) {
View view = super.getView(position, convertView, parent);
TextView textView = ((TextView) view.findViewById(android.R.id.text1));
textView.setMinHeight(0); // Min Height
textView.setMinimumHeight(0); // Min Height
textView.setHeight(100); // Height
return view;
}
};
Now height is fixed to 100. Note that it's the height of text and not the view itself. So keep it in mind when adding padding.
Now set the Adapter:
mylist.setAdapter(myadapter);
Now after every time you add an item to your list call a function as follows:
myarraylist.add(ds.getKey());
myadapter.notifyDataSetChanged();
mylist.setAdapter(myadapter);
setListViewHeightBasedOnItems(mylist);
define the function in same class as:
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);
float px = 500 * (listView.getResources().getDisplayMetrics().density);
item.measure(View.MeasureSpec.makeMeasureSpec((int)px, View.MeasureSpec.AT_MOST), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalItemsHeight += item.getMeasuredHeight();
}
// Get total height of all item dividers.
int totalDividersHeight = listView.getDividerHeight() *
(numberOfItems - 1);
// Get padding
int totalPadding = listView.getPaddingTop() + listView.getPaddingBottom();
// Set list height.
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalItemsHeight + totalDividersHeight + totalPadding;
listView.setLayoutParams(params);
listView.requestLayout();
return true;
} else {
return false;
}
}
You can also check if height is set or not correctly by returning true/false. This solution worked for me. Hope this Helps!!!!!
You have to create a new control that extends the listview overwhriting some functions
public class WrapContentListView extends ListView {
public WrapContentListView(Context context) {
super(context);
}
public WrapContentListView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public WrapContentListView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
#Override
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2,
MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
#Override
public void setAdapter(ListAdapter adapter) {
super.setAdapter(adapter);
setHeightWrapContent();
}
public void setHeightWrapContent() {
ListAdapter listAdapter = getAdapter();
if (listAdapter == null) {
return;
}
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, this);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
ViewGroup.LayoutParams params = this.getLayoutParams();
params.height = totalHeight
+ (this.getDividerHeight() * (listAdapter.getCount() - 1));
this.setLayoutParams(params);
}
}
https://github.com/mzlogin/WrapContentListView/blob/master/app/src/main/java/org/mazhuang/wrapcontentlistview/WrapContentListView.java
Personaly I spent so much time trying to find a solution, turns out all I had to do is to set my listview's height to wrap_content.
use customized listview and give height as wrap_content.