I have a layout which specifies sizes of widgets in relative dimension, for example:
<LinearLayout ... layout_height="fill_parent">
<ImageView ... layout_height="wrap_content" />
<TextView ... layout_height="120dp" />
</LinearLayout>
Immediately after onCreate
, I want to know how much is the height of the ImageView. How to do that?
Note: If I call getHeight()
in onCreate
, I get 0.
I have also tried imageView.postDelayed
, it works on 2.1 emulator but fails on 1.5 emulator (I got 0, too).
Finally, I tried to create a Handler
, and then I call handler.postDelayed
with 10 ms delay. It works in both 2.1 and 1.5 emulator, but failed when I start the program in eclipse debugger (So, I conclude that using the delay doesn't guarantee that the getting of the height happens after the imageview is layout-ted.)
The reason you're getting a size of 0 is that the layout isn't finished until after the activity is fully created, i.e. onCreate(), onStart() and onResume() have all gone through. The easiest way I know of to get the exact size is to call your method after the layout has finished, such as by using a click listener on a button. Since the button isn't displayed until the layout is finished, the size must be available by the time its click listener is fired.
This is only a guess, but I imagine that this is difficult to do precisely because they don't want people messing with layout sizes once the system has just finished laying out the screen. If they provided a "onLayoutFinished()" callback, then you could get yourself stuck in a loop if you modified the layout in that. For example, imagine: layout is completed; onLayoutFinished() called and you modify the layout in there; the existing layout is now invalid; layout re-done; onLayoutFinished() called again; your code gets called again - and so forth.
Another way to do it is to make a custom View and override the onMeasure(int, int)
method. The system triggers that method to get the size of each View; if you use something like my example below, you can get the suggested size before the layout is finished:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
//getMeasuredHeight() and getMeasuredWidth() now contain the suggested size
}
(I wrote that it's the suggested size because I think it's possible for the size to be changed after this based on layout constraints. However, that's a vague memory of something I read a while ago, and I never experimented in detail.) Once you've done that, you can use the size for whatever it is you wanted to do - you can even change the size it will use by using setMeasuredDimension(newX, newY)
.