代码之家  ›  专栏  ›  技术社区  ›  Randy Sugianto 'Yuku'

如何在布局计算后获得Android小部件的大小?

  •  11
  • Randy Sugianto 'Yuku'  · 技术社区  · 14 年前

    我有一个布局,它在相对维度中指定小部件的大小,例如:

    <LinearLayout ... layout_height="fill_parent">
         <ImageView ... layout_height="wrap_content" />
         <TextView ... layout_height="120dp" />
    </LinearLayout>
    

    之后立即 onCreate ,我想知道ImageView的高度是多少。如何做到这一点?

    注: 如果我打电话 getHeight() 在里面 创建时的回调函数 我得到0。

    我也试过了 imageView.postDelayed 它在2.1模拟器上工作,但在1.5模拟器上失败(我也得到了0)。

    最后,我试图创建一个 Handler 然后我打电话给 handler.postDelayed 延迟10毫秒。它在2.1和1.5模拟器中都可以工作,但在Eclipse调试器中启动程序时失败(因此,我得出结论,使用延迟并不能保证在布局ImageView之后获得高度。)

    2 回复  |  直到 12 年前
        1
  •  11
  •   Steve Haley    14 年前

    您获得0大小的原因是,只有在完全创建活动之后,布局才会完成,即onCreate()、onStart()和onResume()都已完成。我所知道的获取准确大小的最简单方法是在布局完成后调用方法,例如使用按钮上的单击侦听器。由于在布局完成之前按钮不会显示,因此在激发其单击侦听器时,大小必须可用。

    这只是一个猜测,但我认为这很难做到,因为他们不希望人们在系统刚完成屏幕布局后就弄乱布局大小。如果他们提供了一个“onlayoutfinished()”回调,那么如果您修改了其中的布局,您可能会陷入一个循环中。例如,假设:布局已完成;调用OnlayoutFinished()并修改其中的布局;现有布局现在无效;布局已重新完成;再次调用OnlayoutFinished();再次调用代码等等。

    另一种方法是创建自定义视图并重写 onMeasure(int, int) 方法。系统触发该方法以获取每个视图的大小;如果您使用类似下面的示例的内容,则可以获取 建议 布局完成前的大小:

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //getMeasuredHeight() and getMeasuredWidth() now contain the suggested size
    }
    

    (我写道,这是建议的大小,因为我认为在此之后,可以根据布局约束更改大小。然而,这是我不久前读到的一个模糊的记忆,我从未做过详细的实验。)一旦你做了这件事,你就可以用这个尺寸来做你想做的任何事情——你甚至可以通过使用 setMeasuredDimension(newX, newY) .

        2
  •  7
  •   securelpb    14 年前

    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
    }