So here is a simple solution to get the dimensions of a view in android. Step 1 − Create a new project in Android Studio,go to File ⇒ New Project and fill all required details to create a new project. Step 2 − Add the following code to res/layout/activity_main. xml.
You can easily get the size of the View by onLayout props. The onLayout handler will also be invoked whenever the view is resized. The main caveat is that the onLayout handler is first invoked one frame after your component has mounted, so you may want to hide your UI until you have computed your layout.
You can use the following method to get the width and height of the view, For example, int height = yourView. getLayoutParams(). height; int width = yourView.
Display display = getWindowManager(). getDefaultDisplay(); Point size = new Point(); display. getSize(size); int width = size. x; int height = size.
I believe the OP is long gone, but in case this answer is able to help future searchers, I thought I'd post a solution that I have found. I have added this code into my onCreate()
method:
EDITED: 07/05/11 to include code from comments:
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);
}
}
});
First I get a final reference to my TextView
(to access in the onGlobalLayout()
method). Next, I get the ViewTreeObserver
from my TextView
, and add an OnGlobalLayoutListener
, overriding onGLobalLayout
(there does not seem to be a superclass method to invoke here...) and adding my code which requires knowing the measurements of the view into this listener. All works as expected for me, so I hope that this is able to help.
I'll just add an alternative solution, override your activity's onWindowFocusChanged method and you will be able to get the values of getHeight(), getWidth() from there.
@Override
public void onWindowFocusChanged (boolean hasFocus) {
// the height will be set at this point
int height = myEverySoTallView.getMeasuredHeight();
}
You are trying to get width and height of an elements, that weren't drawn yet.
If you use debug and stop at some point, you'll see, that your device screen is still empty, that's because your elements weren't drawn yet, so you can't get width and height of something, that doesn't yet exist.
And, I might be wrong, but setWidth()
is not always respected, Layout
lays out it's children and decides how to measure them (calling child.measure()
), so If you set setWidth()
, you are not guaranteed to get this width after element will be drawn.
What you need, is to use getMeasuredWidth()
(the most recent measure of your View) somewhere after the view was actually drawn.
Look into Activity
lifecycle for finding the best moment.
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
I believe a good practice is to use OnGlobalLayoutListener
like this:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!mMeasured) {
// Here your view is already layed out and measured for the first time
mMeasured = true; // Some optional flag to mark, that we already got the sizes
}
}
});
You can place this code directly in onCreate()
, and it will be invoked when views will be laid out.
Use the View's post method like this
post(new Runnable() {
@Override
public void run() {
Log.d(TAG, "width " + MyView.this.getMeasuredWidth());
}
});
I tried to use onGlobalLayout()
to do some custom formatting of a TextView
, but as @George Bailey noticed, onGlobalLayout()
is indeed called twice: once on the initial layout path, and second time after modifying the text.
View.onSizeChanged()
works better for me because if I modify the text there, the method is called only once (during the layout pass). This required sub-classing of TextView
, but on API Level 11+ View. addOnLayoutChangeListener()
can be used to avoid sub-classing.
One more thing, in order to get correct width of the view in View.onSizeChanged()
, the layout_width
should be set to match_parent
, not wrap_content
.
Are you trying to get sizes in a constructor, or any other method that is run BEFORE you get the actual picture?
You won't be getting any dimensions before all components are actually measured (since your xml doesn't know about your display size, parents positions and whatever)
Try getting values after onSizeChanged() (though it can be called with zero), or just simply waiting when you'll get an actual image.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With