getMeasuredHeight not gives exact height that should be when view is expended - android

I am trying to get the view's height that would be after expending it. I am using below View.MeasureSpec to measure.
public static void expand(View summary) {
//set Visible
summary.setVisibility(View.VISIBLE);
summary.measure(
View.MeasureSpec.makeMeasureSpec(((View)summary.getParent()).getMeasuredWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
ValueAnimator mAnimator = slideAnimator(0, summary.getMeasuredHeight(), summary);
mAnimator.start();
}
Folling this Android getMeasuredHeight returns wrong values ! and http://developer.android.com/reference/android/view/View.MeasureSpec.html
If I get the correct height the layout will be like below
But right now I am getting like below
Please suggest me some solution.

Try using the ViewTreeObserver to notify you when the View has finished measurments and layouting; it should be able to tell you it's exact size then.
Sample code:
ViewTreeObserver vto = view.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
int bodyOffset = 0;
if (textPart != null) {
bodyOffset = textPart.getTop();
}
Log.d(Constants.LOGTAG, "body bottom = " + (body.getBottom() + bodyOffset));
Log.d(Constants.LOGTAG, "ok button top = " + okButton.getTop());
if (body.getBottom() + bodyOffset > okButton.getTop()) {
body.setVisibility(View.GONE);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
} else {
view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
}
}
});

Related

get height of layout that is set to wrap content

I want to get height of linear layout that is set to wrap content. but it is zero.
i try this codes:
final LinearLayout below= (LinearLayout) findViewById(R.id.below);
ViewTreeObserver vto = below.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
width = below.getMeasuredWidth();
height = below.getMeasuredHeight();
}
});
and :
LinearLayout below= (LinearLayout) findViewById(R.id.below);
final int belowh=below.getHeight();
using code:
final LinearLayout below= (LinearLayout) findViewById(R.id.below);
ViewTreeObserver vto = below.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(below.getMeasuredHeight()> 0){
this.below.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = below.getMeasuredWidth();
int height = below.getMeasuredHeight();
}
}
})
;
click here to see
Try this code for getting layout width and height after your view is created
final LinearLayout below= (LinearLayout) findViewById(R.id.below);
below.post(new Runnable()
{
#Override
public void run()
{
Log.i("TAG", "Layout width :"+ below.getWidth());
Log.i("TAG", "Layout height :"+ below.getHeight());
}
});
Hope this help
Try this
final LinearLayout below= (LinearLayout) findViewById(R.id.below);
ViewTreeObserver vto = below.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
if(below.getMeasuredHeight()> 0){
this.below.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int width = below.getMeasuredWidth();
int height = below.getMeasuredHeight();
}
}
})
;
#coder android
If you still stack on this.... please see this. I think this will work perfectly.
The following code is found How to retrieve the dimensions of a view?
final TextView tv = (TextView)findViewById(R.id.image_test);
ViewTreeObserver vto = tv.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
LayerDrawable ld = (LayerDrawable)tv.getBackground();
ld.setLayerInset(1, 0, tv.getHeight() / 2, 0, 0);
ViewTreeObserver obs = tv.getViewTreeObserver();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});

Android - Is there a callback function when a View is all set?

I have a custom View, in which I need to perform treatment that require that the size of the view is set (so onCreate doesn't works), but before displaying anything. So I wondered if there is a callback function tat I could override for that ?
Right now I'm using onLayout, but it seems to be called twice, so I'm assuming it's probably not the right use for this. I also tried doing it in onMeasure but it seems that getWidth() and getHeight still returns 0 in it.
Thkanks,
Robin.
Try to use OnGlobalLayoutListener inside onResume()
#Override
public void onResume(){
super.onResume();
ViewTreeObserver viewTreeObserver = yourView.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
viewWidth = yourView.getWidth();
viewHeight = yourView.getHeight();
yourView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
System.out.println(viewHeight + " on resume x" + yourView.getX());
}
});
}
}
You can use the callback OnSizeChanged.
use onSizeChanged,
#Override
protected void onSizeChanged(int width, int height, int oldwidth, int oldheight) {
super.onSizeChanged(width, height, oldwidth, oldheight);
// your code here.
}
Try those methods
1.
ViewTreeObserver vto2 = imageView.getViewTreeObserver();
vto2.addOnGlobalLayoutListener(new
OnGlobalLayoutListener() {
#Override
public void onGlobalLayout () {
imageView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
int height = imageView.getHeight();
int width = imageView.getWidth();
textView.append("\n\n" + imageView.getHeight() + "," + imageView.getWidth());
}
}
);
2.
imageView.post(new Runnable() {
#Override
public void run () {
int h = imageView.getHeight();
int w = imageView.getWidth();
Log.i(TAG, "Height=" + h);
}
};

measureSpec returns wrong value

I am trying to get measured height of layout by using this code:
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(toExpand.getWidth(), View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
layoutHeight.measure(widthMeasureSpec, heightMeasureSpec);
int height = layoutHeight.getMeasuredHeight();
it returns good values if I call it after layout has been created but I am also calling it on aplication startup when fragment gets attached and then it returns much higher values than expected.
Any ideas? Thanks in forward
Solved this by using onGlobalLayout listener with viewTreeObserver. Here is the code:
ViewTreeObserver vto = ((View) loadingLayout.getParent()).getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
ViewTreeObserver vto = ((View) loadingLayout.getParent()).getViewTreeObserver();
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(toExpand.getWidth(), View.MeasureSpec.EXACTLY);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
layoutHeight.measure(widthMeasureSpec, heightMeasureSpec);
int height = layoutHeight.getMeasuredHeight();
if(toExpand.getHeight() == height){
hide(toExpand, 0);
}else{
expand(toExpand, height);
}
if (Build.VERSION.SDK_INT < 16) {
//deprecated od API level 16
vto.removeGlobalOnLayoutListener(this);
} else {
vto.removeOnGlobalLayoutListener(this);
}
}
});

check if an android scrollview can scroll

Do you know if it is possible to know if an Android Widget ScrollView can scroll?
If it has enough space it doesn't need to scroll, but as soon as a dimension exceeds a maximum value the widget can scroll.
I don't see in the reference a method who can give this information.
Maybe is it possible to do something with the size of the linearlayout inside the scrollview?
I used the following code inspired by https://stackoverflow.com/a/18574328/3439686 and it works!
ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
int childHeight = ((LinearLayout)findViewById(R.id.scrollContent)).getHeight();
boolean isScrollable = scrollView.getHeight() < childHeight + scrollView.getPaddingTop() + scrollView.getPaddingBottom();
Thanks to: #johanvs and https://stackoverflow.com/a/18574328/3439686
private boolean canScroll(HorizontalScrollView horizontalScrollView) {
View child = (View) horizontalScrollView.getChildAt(0);
if (child != null) {
int childWidth = (child).getWidth();
return horizontalScrollView.getWidth() < childWidth + horizontalScrollView.getPaddingLeft() + horizontalScrollView.getPaddingRight();
}
return false;
}
private boolean canScroll(ScrollView scrollView) {
View child = (View) scrollView.getChildAt(0);
if (child != null) {
int childHeight = (child).getHeight();
return scrollView.getHeight() < childHeight + scrollView.getPaddingTop() + scrollView.getPaddingBottom();
}
return false;
}
In addition to #johanvs response:
You should wait for view beign displayed
final ScrollView scrollView = (ScrollView) v.findViewById(R.id.scrollView);
ViewTreeObserver viewTreeObserver = scrollView.getViewTreeObserver();
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
scrollView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
int childHeight = ((LinearLayout) v.findViewById(R.id.dataContent)).getHeight();
boolean isScrollable = scrollView.getHeight() < childHeight + scrollView.getPaddingTop() + scrollView.getPaddingBottom();
if (isScrollable) {
//Urrah! is scrollable
}
}
});

Measure view in fragment

I need to know ImageView width and height. Is there a way to measure it in fragment ? In standard Activity I use this :
#Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
image.getWidth();
image.getHeight();
}
But where can I use image.getWidth(); and image.getHeight(); in fragment ?
Use the GlobalLayoutListener. You assign the listener to your ImageView in onCreateView() just like you do in that answer in the link. It also is more reliable than onWindowFocusChanged() for the main Activity so I recommend switching strategies.
EDIT
Example:
final View testView = findViewById(R.id.view_id);
ViewTreeObserver vto = testView.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Log.d("TEST", "Height = " + testView.getHeight() + " Width = " + testView.getWidth());
ViewTreeObserver obs = testView.getViewTreeObserver();
obs.removeGlobalOnLayoutListener(this);
}
});

Categories

Resources