计算布局后如何获取Android小部件的大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2864331/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get an Android widget's size after layout is calculated?
提问by Randy Sugianto 'Yuku'
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?
紧接着onCreate
,我想知道ImageView的高度是多少。怎么做?
Note:If I call getHeight()
in onCreate
, I get 0.
注:如果我打电话getHeight()
的onCreate
,我得到0。
I have also tried imageView.postDelayed
, it works on 2.1 emulator but fails on 1.5 emulator (I got 0, too).
我也试过imageView.postDelayed
,它在 2.1 模拟器上工作,但在 1.5 模拟器上失败(我也得到了 0)。
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.)
最后,我尝试创建一个Handler
,然后handler.postDelayed
以 10 毫秒的延迟调用。它适用于 2.1 和 1.5 模拟器,但是当我在 eclipse 调试器中启动程序时失败(因此,我得出结论,使用延迟并不能保证在对图像视图进行布局之后获得高度。)
采纳答案by Steve Haley
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.
您得到大小为 0 的原因是在完全创建活动之后布局才完成,即 onCreate()、onStart() 和 onResume() 都已经完成。我知道获得确切大小的最简单方法是在布局完成后调用您的方法,例如通过在按钮上使用单击侦听器。由于按钮在布局完成之前不会显示,因此在触发其单击侦听器时必须提供大小。
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.
这只是一个猜测,但我认为这很难准确地做到,因为他们不希望人们在系统刚刚完成屏幕布局后搞乱布局大小。如果他们提供了“onLayoutFinished()”回调,那么如果您修改了布局,您可能会陷入循环。例如,想象一下:布局完成;调用 onLayoutFinished() 并在其中修改布局;现有布局现在无效;重新布局;onLayoutFinished() 再次调用;您的代码再次被调用 - 依此类推。
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 suggestedsize before the layout is finished:
另一种方法是创建自定义视图并覆盖该onMeasure(int, int)
方法。系统触发该方法获取每个View的大小;如果您使用类似于我下面的示例的内容,则可以在布局完成之前获得建议的尺寸:
@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)
.
(我写道这是建议的大小,因为我认为在此之后根据布局限制可能会更改大小。但是,这是我前段时间阅读的内容的模糊记忆,我从未进行过详细实验。)一旦你这样做之后,您可以将大小用于您想做的任何事情 - 您甚至可以使用setMeasuredDimension(newX, newY)
.
回答by securelpb
The View object provides method called onSizeChanged(int w, int h, int oldw, int oldh). It is called when the layout changes the size of one of its components. If you override this method then the the code in your version of this method will know the size of itself as shown in the following snippet.
View 对象提供了称为 onSizeChanged(int w, int h, int oldw, int oldh) 的方法。当布局更改其组件之一的大小时调用它。如果您覆盖此方法,则此方法版本中的代码将知道自身的大小,如以下代码段所示。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
bounds = new Rect();
this.getDrawingRect(bounds);
// bounds will now contain none zero values
}