I have a gridlayout who's size I want to check before displaying anything in the activity, because I want to check if an image needs to be resized. Can't do it OnStart() because apparently it hasn't been loaded yet. Adding a listener doesn't work due to synchronization issues with the rest of the code. It would be nice if I could just manually generate the value, by using the dimensions of the device, but I for the life of me can't find the exact value of those stupid margins Android places automatically. Any suggestions? Essentially in the code below I need to have height/width of the GridLayout BEFORE SplitImage() is called.
XML
<GridLayout
android:id="#+id/grid_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:useDefaultMargins="false" >
</GridLayout>
Relevant JAVA
public class GamePlay extends Activity {
int difficulty = 0;
int image = 0;
int widthView = 0;
int heightView = 0;
int boardW;
int boardH;
int nSqr;
Bitmap[][] gameBoard;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
Intent intent = getIntent();
difficulty = intent.getIntExtra("DIFFICULTY_KEY_DMIROU246", 0);
image = intent.getIntExtra("LEVEL_KEY_DMIROU246", 0);
setContentView(R.layout.activity_game_play);
Log.w("Derp", "1");
}
#Override
protected void onStart() {
super.onStart();
View view = (View) findViewById(R.id.grid_layout);
Log.w("Derp", "2");
heightView = view.getHeight();
widthView = view.getWidth();
Log.w("Derp", "3");
gameBoard = SplitImage();
Log.w("Derp", "9");
}
You won't get the height or width of the view until it is drawn on the screen.
For this purpose you'll have two ways to get the hight and width of a layout:-
1) ViewTreeObserver--Doc
View view = (View) findViewById(R.id.grid_layout);
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
gameBoard = SplitImage();
Log.w("Derp", "9");
}
});
2) Handler.postDelayed--Doc
View view = (View) findViewById(R.id.grid_layout);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
#Override
public void run() {
int width = view.getMeasuredWidth();
int height = view.getMeasuredHeight();
gameBoard = SplitImage();
Log.w("Derp", "9");
}
}, 500);
The easiest solution is to do this asynchronously, use view.getViewTreeObserver then add a OnGlobalLayoutListener that will get the size of your view and call splitImage().
Take care that your listener is not called to often, the best is to remove it after it has been triggered once.
Try This One
Problem:I have some data show as list (Expandable view).
Main list view Show i am Using List View and show Child view Display another inner listview used.so child view can not calculate cell heigt.
1) i have both UI TABLAT and PHONE
2) if any user any problem implement time this code so contact me i will help you."rp1741995#gmail.com"
public static int getListViewHeightBasedOnChildren(ListView listView,Context context) {
ListAdapter listAdapter = listView.getAdapter();
if (listAdapter != null)
{
int totalHeight = 0;
int size = listAdapter.getCount();
Log.e(TAG, "getListViewHeightBasedOnChildren: >>"+size);
for (int i = 0; i < size; i++)
{
View listItem = listAdapter.getView(i, null, listView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
}
totalHeight = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount()-1));
if(listAdapter.getCount()!=0) {
if (MyApplication.isTablet(context)) {
Float height = convertDpToPixel(10);
totalHeight = (totalHeight / listAdapter.getCount()) + Math.round(height);
}else {
Float height = convertDpToPixel(80);
totalHeight = (totalHeight / listAdapter.getCount()) + Math.round(height);
}
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
params.height = totalHeight;
//params.height;
Log.e(TAG, "getListViewSize: "+String.valueOf(totalHeight));
listView.setLayoutParams(params);
return totalHeight;
}
return 0;
}
Related
I have Listview having comment listing with different height of each row according to comment length. I want to give height to the listview programmatically. I tried to get height of each row, but every time I get the same height for each row.. but each row has different size according to their content. I have used following code:
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, View.MeasureSpec.UNSPECIFIED);
totalItemsHeight += item.getMeasuredHeight();
Log.e("HEIGHT", "" + 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();
}
You have to wait for it to be laid out and measured.
If you want to force it to do this early for an item which wraps content you can call measure like this:
item.measure(MeasureSpec.makeMeasureSpec(maxWidth, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(maxHeight, MeasureSpec.AT_MOST));
Before calling getMeasuredHeight. Remember though, that this will return pixels not dp so you may need to do some conversion.
Try using ViewTreeObserver :
int mViewHeight =WindowManager.LayoutParams.WRAP_CONTENT;
callAddOnGlobalLayoutListner(item);
Method ::
public void callAddOnGlobalLayoutListener(final View v){
view.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#SuppressWarnings("deprecation")
#Override
public void onGlobalLayout() {
// TODO Auto-generated method stub
v.getViewTreeObserver()
.removeGlobalOnLayoutListener(this);
mViewHeight = view.getMeasuredHeight();
Log.d("Height",mViewHeight+"");
}
}
});
}
I had a problem that stems from the fact that Android has certain difficulty with nested scrolling elements.
I have a ScrollView that hosts a horizontal RecyclerView and an ExpandableListView just beneath it.
The issue I encountered was that the ScrollView didn't scroll.
I fixed it by :
1. setting fixed height to the RecyclerView.
2. calculating the ExpandableListView height with each group item click.
Like this:
expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
#Override
public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {
setListViewHeight(parent, groupPosition);
return false;
}
});
private void setListViewHeight(ExpandableListView listView, int group) {
ExpandableListAdapter listAdapter = (ExpandableListAdapter) listView.getExpandableListAdapter();
int totalHeight = 0;
int desiredWidth = View.MeasureSpec.makeMeasureSpec(listView.getWidth(),View.MeasureSpec.EXACTLY);
for (int i = 0; i < listAdapter.getGroupCount(); i++) {
View groupItem = listAdapter.getGroupView(i, false, null, listView);
groupItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (((listView.isGroupExpanded(i)) && (i != group)) || ((!listView.isGroupExpanded(i)) && (i == group)))
{
for (int j = 0; j < listAdapter.getChildrenCount(i); j++)
{
View listItem = listAdapter.getChildView(i, j, false, null,listView);
listItem.measure(desiredWidth, View.MeasureSpec.UNSPECIFIED);
totalHeight += listItem.getMeasuredHeight();
}
}
}
ViewGroup.LayoutParams params = listView.getLayoutParams();
int height = totalHeight + (listView.getDividerHeight() * (listAdapter.getGroupCount() - 1));
if (height < 10)
height = 200;
params.height = height;
listView.setLayoutParams(params);
listView.requestLayout();
}
Problem :
since I calculate the listview height only on group item click, when I just open the fragment and up until I click on a group item, the ScrollView doesn't work.
I have found that calculating the height of the ExpandableListView adapter in onCreateView is problematic since it is still empty at that point.
Any ideas would be much apreciated.
If you need to wait until the view has been laid out, you can use
a ViewTreeObserver. For example :
protected void onCreate(Bundle savedInstanceState) {
...
final View someView = findViewById(R.id.some_id);
someView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
public void onGlobalLayout() {
// the values are now available
int mesuredHeight = someView.getMeasuredHeight();
int height = someView.getHeight();
// done, remove the observer
someView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
});
...
}
I have created a GridView control, which inhertis from a ScrollView, the idea of this control, is that it will contain multiple Views arranged in a grid format with a given number of columns and rows.
When the view is first built, the GridView doesn't know the size of its container, so I wait until the onSizeChanged method is called, then I apply the relevant sizing.
When the below is run, it doesn't re-size the grid to show it correctly, each control is only as big as it needs to be to show the text.
When the `onSizeChanged' method is called, it has the correct size, and applies the correct size to each child view, but it doesn't affect the way the controls are drawn (i.e. they're still all bunched up on the top left of the screen).
Despite this, I have actually got it working, but it draws twice. I do this by creating a Runnable which calls ResizeList. Then calling new Handler().post(r) straight after I call BuildIt.
Although this is a solution, I just don't understand why it doesn't work in the below form.
Incidentally, if the GridView is the main View added to the Activity, it displays fine, it's only when it's subsequently added. Which is why I have the Button, which you have to press to show the grid.
Can anyone suggest why the below code doesn't work properly?
public class MainActivity extends Activity {
GridView sv;
FrameLayout flay;
#Override protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
flay=new FrameLayout(this);
this.setContentView(flay);
Button b=new Button(this);
b.setText("press me to show grid view");
b.setOnClickListener(ocl);
flay.addView(b);
}
OnClickListener ocl=new OnClickListener()
{
#Override public void onClick(View v)
{
BuildIt();
}};
private void BuildIt()
{
flay.removeAllViews(); // remove the button control
sv=new GridView(this);
for (int c1=0 ; c1<30 ; c1++)
{
TextView tv=new TextView(this);
tv.setText("Item "+c1);
tv.setGravity(android.view.Gravity.CENTER);
sv.addListItem(tv);
}
flay.addView(sv);
sv.ConstructList();
}
}
The GridView class
public class GridView extends ScrollView
{
final int rows=4;
final int cols=4;
private ArrayList<View> allViews=new ArrayList<View>();
private LinearLayout ll;
public GridView(Context context)
{
super(context);
ll=new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);
this.addView(ll);
}
public void addListItem(View v)
{
allViews.add(v);
}
public void ConstructList()
{
int c1=0;
ll.removeAllViews(); // Just in case we're re-building
LinearLayout row=null;
for (View v : allViews)
{
if (c1%cols==0)
{
row=new LinearLayout(this.getContext());
ll.addView(row);
}
row.addView(v);
c1++;
}
}
private void ResizeList()
{
int useHeight=getHeight()/rows;
int useWidth=getWidth()/cols;
LinearLayout.LayoutParams lpCol=new LinearLayout.LayoutParams(useWidth, useHeight);
Log.i("log","About to set width/height="+useWidth+"/"+useHeight);
int numKids= ll.getChildCount();
for (int c1=0 ; c1<numKids ; c1++)
{
LinearLayout ll2=(LinearLayout)ll.getChildAt(c1);
for (int c2=0 ; c2<ll2.getChildCount() ; c2++) // use getChildCount rather than cols, just in case it's the last one
{
View v=ll2.getChildAt(c2);
v.setLayoutParams(lpCol);
}
}
}
#Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
super.onSizeChanged(w, h, oldw, oldh);
ResizeList();
}
}
I have a function which is used to resize the child's width and height in gridView.
May be this could help you :
public static void setGridChild_Height(GridView gridView, int columns) {
ListAdapter listAdapter = gridView.getAdapter();
if (listAdapter == null) {
// pre-condition
return;
}
int totalHeight = 0;
int items = listAdapter.getCount();
int rows = 0;
for (int j = 0; j < items; j++) {
View view = gridView.getChildAt(j);
if (view != null && view.getHeight() > totalHeight) {
totalHeight = view.getHeight();
}
}
System.out.println("totalHeight -> " + totalHeight);
if (totalHeight > 0) {
for (int j = 0; j < items; j++) {
View view = gridView.getChildAt(j);
if (view != null && view.getHeight() < totalHeight) {
view.setMinimumHeight(totalHeight);
}
}
}
// View listItem = listAdapter.getView(0, null, gridView);
// 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);
}
Try to change logic as per your requirement.
Code is not tested perfectly.
It's because onSizeChanged when newly added to the view hierarchy uses it's old sizes of "0" (according to the docs: http://developer.android.com/reference/android/view/View.html#onSizeChanged(int, int, int, int))
I think what you want is to a addOnLayoutChangedListener : http://developer.android.com/reference/android/view/View.html#addOnLayoutChangeListener(android.view.View.OnLayoutChangeListener)
Using the ViewTreeObserver might be another option that will work for you: How can you tell when a layout has been drawn?
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.
I am using expandable list view to make 3 - level hierarchy, would like to know how to set internal list height and width.
I knew we have onMeasure for this purpose but in my case it not allowing me to capture whole space of parent list view.
may be I am giving wrong value to it, here is the code which is I am using for setting height and width of child expandable list.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
widthMeasureSpec = MeasureSpec.makeMeasureSpec(960,MeasureSpec.AT_MOST);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(800,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
Currently it appearing as follow
<ParentGroup1 >
<ChildParentGroup>
<Child1>
<Child2>
<child3>
<ParentGroup2 >
and it should appear like below.
<ParentGroup1 >
<ChildParentGroup >
<Child1 >
<Child2 >
<child3 >
<ParentGroup2 >
Please advise/suggest for the same.
Thanks for your time.
Not sure if you're still looking for an answer, but this is how I did it: pass a reference to the parent view and a height measure (in this case, I used the size of the child list) in the constructor to create the child custom list.
public CustomExpandableList(Context context, View the_parentView, int the_heightMeasure)
{
super(context);
WIDTH = the_parentView!=null?the_parentView.getWidth():LayoutParams.MATCH_PARENT;
HEIGHT = the_heightMeasure * 500;
}
EDIT: Or to make the code more consistent, you could pass the width of the parentView and height measure to the constructor instead of passing the parent view itself.
CustomExpandableList(Context the_context, int the_width, int the_heightMeasure)
use this code to calculate expandable list view dynamically:
// calculate the height of expandable listView without expanded
private void setListViewHeight(ExpandableListView expListView) {
ListAdapter listAdapter = expListView.getAdapter();
int totalHeight = 0;
for (int i = 0; i < listAdapter.getCount(); i++) {
View listItem = listAdapter.getView(i, null, expListView);
listItem.measure(0, 0);
totalHeight += listItem.getMeasuredHeight();
System.out.println("i " + i);
}
ViewGroup.LayoutParams params = expListView.getLayoutParams();
params.height = totalHeight
+ (expListView.getDividerHeight() * (listAdapter.getCount() - 1));
System.out.println("params.height = " + params.height);
expListView.setLayoutParams(params);
expListView.requestLayout();
}
// calculate the height of expandable listview dynamically
private void setListViewHeight(ExpandableListView expListView, int group) {
ExpandableListAdapter listAdapter = expListView
.getExpandableListAdapter();
int totalHeight = 0;
int desiredWidth = MeasureSpec.makeMeasureSpec(expListView.getWidth(),
MeasureSpec.UNSPECIFIED);
for (int i = 0; i < listAdapter.getGroupCount(); i++) {
View groupItem = listAdapter.getGroupView(i, false, null,
expListView);
groupItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (((expListView.isGroupExpanded(i)) && (i == group))
|| ((!expListView.isGroupExpanded(i)) && (i == group))) {
for (int j = 0; j < listAdapter.getChildrenCount(i); j++) {
View listItem = listAdapter.getChildView(i, j, false, null,
expListView);
Log.e("Count", listAdapter.getChildrenCount(i) + "");
listItem.setLayoutParams(new ViewGroup.LayoutParams(
desiredWidth, MeasureSpec.UNSPECIFIED));
// listItem.measure(desiredWidth, MeasureSpec.UNSPECIFIED);
listItem.measure(MeasureSpec.makeMeasureSpec(0,
MeasureSpec.UNSPECIFIED), MeasureSpec
.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
totalHeight += listItem.getMeasuredHeight();
System.out.println("totalHeight" + totalHeight);
Log.e("TEST", "gshdkfmjfy,");
}
}
}
ViewGroup.LayoutParams params = expListView.getLayoutParams();
int height = totalHeight
+ (expListView.getDividerHeight() * (listAdapter
.getGroupCount() - 1));
if (height < 10) {
height = 100;
}
params.height = height;
expListView.setLayoutParams(params);
expListView.requestLayout();
}
I succeeded in some days ago by doing this. It's a little bit more compact and without any additionnal parameter, and it works perfectly.
public static void setExpandableListViewHeightBasedOnChildren(ExpandableListView expandableListView){
ExpandableNotesListAdapter adapter = (ExpandableNotesListAdapter) expandableListView.getExpandableListAdapter();
if (adapter == null){
return;
}
int totalHeight = expandableListView.getPaddingTop() + expandableListView.getPaddingBottom();
for (int i = 0 ; i < adapter.getGroupCount() ; i++){
View groupItem = adapter.getGroupView(i, false, null, expandableListView);
groupItem.measure(View.MeasureSpec.UNSPECIFIED,View.MeasureSpec.UNSPECIFIED);
totalHeight += groupItem.getMeasuredHeight();
if (expandableListView.isGroupExpanded(i) ){
for( int j = 0 ; j < adapter.getChildrenCount(i) ; j++) {
View listItem = adapter.getChildView(i, j, false, null, expandableListView);
listItem.setLayoutParams(new LayoutParams(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED));
listItem.measure(View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalHeight += listItem.getMeasuredHeight();
}
}
}
ViewGroup.LayoutParams params = expandableListView.getLayoutParams();
int height = totalHeight + expandableListView.getDividerHeight() * (adapter.getGroupCount() - 1);
if (height < 10)
height = 100;
params.height = height;
expandableListView.setLayoutParams(params);
expandableListView.requestLayout();
}
Don't forget to add this when you init your View, set your adapter, etc. :
Functions.setExpandableListViewHeightBasedOnChildren(listView);
listView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
#Override
public void onGroupExpand(int groupPosition) {
Functions.setExpandableListViewHeightBasedOnChildren(listView);
}
});
Create one layout xml file for ParentGroup and ChildParentGroup , another layout xml file for Child. Now you are problem is reduced to two level hierarchy. Then In Expandable listview we have Parent view and childview methods to inflate and use the Parent and Child layouts. So in that mehods you can do whatever you want.
Simply remove the width code and it should work fine.
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
heightMeasureSpec = MeasureSpec.makeMeasureSpec(999999, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
I know its late, but if anyone has the same issue. You can solve it by creating a Custom ExpandableListView and using "MeasureSpec.EXACTLY":
public class CustomExpListView extends ExpandableListView{
public CustomExpListView(Context context){
super(context);
}
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.EXACTLY);
heightMeasureSpec = MeasureSpec.makeMeasureSpec(20000, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
}
Hope this helps to anyone. For me its working.
Adding to muhammadSalem's answer. This is how I solved my problem by calculating the height of expandableListView's children's total height.
private fun getSubItemTotalHeight(groupPosition: Int): Int {
val children: Int = mAdapter.getChildrenCount(groupPosition)
val desiredWidth: Int = View.MeasureSpec.makeMeasureSpec(mExpandableListView.width,
View.MeasureSpec.UNSPECIFIED)
var subItemTotalHeight = 0
repeat(children) {
val child = mAdapter.getChildView(groupPosition, it, true, null, null)
child.layoutParams = ViewGroup.LayoutParams(
desiredWidth, View.MeasureSpec.UNSPECIFIED)
child.measure(View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec
.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED))
subItemTotalHeight += child.measuredHeight
}
val dividerCount = children - 1
val dividerTotalCount = (dividerCount * mExpandableListView.dividerHeight).toFloat()
showToast(mExpandableListView.dividerHeight.toString())
val totalDividerPixels = TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
dividerTotalCount,
resources.displayMetrics
)
return subItemTotalHeight + totalDividerPixels.toInt()
}
One thing to note is that if you added a divider height for your expandableListview, you should include the calculations for it. What I did is convert the total divider height which is in dp into pixels and added it into the totalHeight. This solved the clipping issues I encountered.
Then to use it would be just :
mExpandableListView.setOnGroupExpandListener { groupPosition ->
mExpandableListView.layoutParams.height += getSubItemTotalHeight(groupPosition)
mExpandableListView.requestLayout()
}
mExpandableListView.setOnGroupCollapseListener { groupPosition ->
mExpandableListView.layoutParams.height -= getSubItemTotalHeight(groupPosition)
mExpandableListView.requestLayout()
}