i have ExpandableListview inside ScrollView and i know that's not good but i had too, the only solution to show the whole list is by set its height by code using layoutParams
RelativeLayout.LayoutParams params = new
RelativeLayout.LayoutParams(LayoutParams.MATCH_PARENT,
ListViewData.length());
this solution is good but i can't figure the right height that i should give in the Params, SO is there a way to know the actual size from the size of the array
Edit:
i came up with a solution that everytime i expand a group of the list am gonna change the height to fit with new geight
try this, Use Child based on listview. setListViewHeightBasedOnChildren() this will set your listview child based height
public class Utils {
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);
listView.requestLayout();
}
}
Your ListView is effectively unneeded in this case. You can as well loop over your adapter's items and just add them to a vertical LinearLayout inside your ScrollView.
In case you do not want to change a lot of code:
Replace ListView.setAdapter with
LinearLayout ll; //this should be the vertical LinearLayout that you substituted the listview with
for(int i=0;i<adapter.getCount();i++) {
View v = adapter.getView(position, null, null);
ll.addView(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
}
If you already use an OnItemClickListener add after View v = adapter.getView(position, null, null); the following
final int position = i;
v.setOnClickListener(new OnClickListener() {
public onClick(View v) {
yourOnItemClickListener.onItemClick(null, v, position, 0);
}
});
In this case you do not have to worry about any miscalculation in the height.
Try this, it works for my same problem
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;
}}
requestLayout() method is called on the view because something has changed that invalidated its layout - forces redrawing.
you can set a variable in dimensions file for different screen sizes and then multiply it by the number of items of list you want to display.
Related
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);
}
Is it possible to determine the height of a ListView before it is rendered on the screen? If my ListView were to have, say 3 items, and the height is confined to these 3 items (and the ListView doesn't take up the entire screen's height), can I determine the height before Android displays the items on the screen?
Use the following method to get and set the height based upon children present
private static void setListViewHeightBasedOnChildren(ListView iListView) {
ListAdapter listAdapter = iListView.getAdapter();
if (listAdapter == null)
return;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(iListView.getWidth(), View.MeasureSpec.UNSPECIFIED);
int totalHeight = 0;
View view = null;
for (int i = 0; i < listAdapter.getCount(); i++) {
view = listAdapter.getView(i, view, iListView);
if (i == 0)
view.setLayoutParams(new ViewGroup.LayoutParams(desiredWidth, RelativeLayout.LayoutParams.WRAP_CONTENT));
view.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += view.getMeasuredHeight();
}
ViewGroup.LayoutParams params = iListView.getLayoutParams();
params.height = totalHeight + (iListView.getDividerHeight() * (listAdapter.getCount() - 1));
Log.d("TAG", "ListView Height --- "+params.height);
iListView.setLayoutParams(params);
iListView.requestLayout();
}
You will have to calculate the height yourself if you have kept the height of each item fixed. A view can't return its height before it is made
I used listview inside scrollview and used this code to update listview height:
// method to expand the height of listview
public void updateListViewHeight(ListView list) {
CustomeAdapter myListAdapter = (CustomeAdapter) list.getAdapter();
if (myListAdapter == null) {
return;
}
// get listview height
int totalHeight = 0;
// int adapterCount = myListAdapter.getCount();
for (int size = 0; size < Math.max(shoutsList.size(), postsList.size()); size++) {
View listItem = myListAdapter.getView(size, null, list);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
// Change Height of ListView
ViewGroup.LayoutParams params = list.getLayoutParams();
params.height = totalHeight
+ (list.getDividerHeight() * (shoutsList.size() - 1));
list.setLayoutParams(params);
}
The problem is that I request new data from server when the user scroll down, but when I update listview height it auto scroll and request data automatically
I have a ScrollView which contains a lot of items. On the bottom of it I add a set of items from another Activity. I check the input ArrayList from another Activity and should to add proper count of checkbox to my Activity with ScrollView. I add items with the help of LinearLayout like that:
public void addFiles()
{
adapter = new ArrayAdapter<File>(this,
R.layout.new_order, R.id.fileCheck,
FileManagerActivity.finalAttachFiles)
{
#Override
public View getView(final int position, View convertView, ViewGroup parent) {
// creates view
LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.file, null);
view.setFocusable(false);
CheckBox textView = (CheckBox) view
.findViewById(R.id.fileCheck);
textView.setClickable(true);
textView.setText(FileManagerActivity.finalAttachFiles.get(position).getName().toString());
textView.setTextColor(Color.BLACK);
textView.setPadding(55, 0, 0, 0);
textView.setCompoundDrawablesWithIntrinsicBounds(R.drawable.file_icon, 0, 0, 0);
textView.setTextSize(16);
textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
int dp5 = (int) (5 * getResources().getDisplayMetrics().density + 0.5f);
textView.setCompoundDrawablePadding(dp5);
textView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if(((CheckBox)v).isChecked()){
checks.set(position, 1);
}
else{
checks.set(position, 0);
}
}
});
return view;
}
};
}
I know that using ListView inside a ScrollView is not recomended but I tried to use LinearLayout for my aim, but it worked bad - it couldn't updated properly. To display ListView in proper way I use such a class:
public class UtilityListView {
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);
Log.i("ListAdapter count",Integer.toString(listAdapter.getCount()));
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();
}
}
And use it after every data changing like that:
fileList = (ListView) findViewById(R.id.fileListView);
fileList.setAdapter(adapter);
UtilityListView.setListViewHeightBasedOnChildren(fileList);
But the height of the ListView is much bigger than quantity of items of the list...How can I fix it?
I solved the problem using the ListView with footers and headers. All the attempts to use ListView inside the ScrollView were unworkable or unefficient. I did it like this:
View header = getLayoutInflater().inflate(R.layout.header_listview, null);
View footer = getLayoutInflater().inflate(R.layout.footer_listview, null);
fileList.addHeaderView(header);
fileList.addFooterView(footer);
fileList.setCacheColorHint(Color.WHITE);
fileList.setAdapter(adapter);
All my items shows properly and I can get functionality, what I wanted.
I have nested listView. How to force height of listView to be size so that every row is visible ?
ListView is nested inside ScrollView so scroll doesn't work for ListView so I need to make that all items are visible inside ListView which is nested ion ScrollView ( there is above and bellow more things).
To calculate hieght of listView
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();
}
Pass listview object to this methode.
setListViewHeightBasedOnChildren(listView)
you can use this code.listview contains this attribute
android:minheight="20dp";