在onCreate中获取内容视图大小

时间:2013-09-17 23:34:31

标签: android

我正在寻找一种衡量Android活动实际内容区域尺寸的好方法。

获取显示始终有效。简单地说就是这样:

Display display = getWindowManager().getDefaultDisplay();

您可以获得整个屏幕的像素数。当然,这不会考虑ActionBar,状态栏或任何其他会减少活动本身可用大小的视图。

活动开始后,您可以执行以下操作:

View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);

仅获取活动内容。但是在onCreate()中执行此操作将导致宽度和高度为0的视图。

在onCreate期间有没有办法获得这些尺寸?我想应该有一种方法可以测量任何状态栏并从总显示大小中减去它,但我无法找到一种方法。我认为这是唯一的方法,因为内容窗口方法总是在绘制之前返回没有宽度/高度的视图。

谢谢!

6 个答案:

答案 0 :(得分:29)

根据您的目标,您可以使用布局或预绘制侦听器。例如,在onCreate()中:

final View content = findViewById(android.R.id.content);
content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        //Remove it here unless you want to get this callback for EVERY
        //layout pass, which can get you into infinite loops if you ever
        //modify the layout from within this method.
        content.getViewTreeObserver().removeGlobalOnLayoutListener(this);

        //Now you can get the width and height from content
    }
});

<强>更新 从API 16 removeGlobalOnLayoutListener开始不推荐使用。

更改为: content.getViewTreeObserver().removeOnGlobalLayoutListener(this)

答案 1 :(得分:18)

(从my answer to a related question复制)

我使用以下技术 - 发布将在创建视图时执行的onCreate()的runnable:

    contentView = findViewById(android.R.id.content);
    contentView.post(new Runnable()
    {
        public void run()
        {
            contentHeight = contentView.getHeight();
        }
    });

此代码将在onCreate()完成后在主UI线程上运行。

答案 2 :(得分:2)

这似乎是一个重复的问题。在这个SO问题中有一个优雅的答案:

getWidth() and getHeight() of View returns 0

哪个(无耻地复制)是覆盖onWindowFocusChanged(),它似乎在onCreate()之后触发,并且渲染大小:

@Override
 public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  //Here you can get the size!
 }

答案 3 :(得分:2)

使用post的答案是错误的,因为可能不会重新计算大小。
另一个重要的事情是,视图及其所有祖先必须可见。为此,我使用属性View.isShown

这是我的kotlin函数,可以将其放置在utils中:

fun View.onInitialized(onInit: () -> Unit) {
    viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
        override fun onGlobalLayout() {
            if (isShown) {
                viewTreeObserver.removeOnGlobalLayoutListener(this)
                onInit()
            }
        }
    })
}

用法是:

myView.onInitialized {
    Log.d(TAG, "width is: " + myView.width)
}

答案 4 :(得分:0)

如果要将位图加载到ImageView中的OnCreate()中,可以使用以下示例进行操作:

public static void setImageLater(@NonNull final ImageView imageView,final Bitmap bitmap){
    final ViewTreeObserver observer = imageView.getViewTreeObserver();
    observer.addOnGlobalLayoutListener(
            new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    imageView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    imageView.setImageBitmap(bitmap);
                }
            });
}

答案 5 :(得分:-2)

您可以在onResume中执行任何需要大小的工作(使用alreadyDone之类的标记,每次Activity前进时都不要重复它。在onCreate视图中不显示,因此大小为零是正常的。