我正在寻找一种衡量Android活动实际内容区域尺寸的好方法。
获取显示始终有效。简单地说就是这样:
Display display = getWindowManager().getDefaultDisplay();
您可以获得整个屏幕的像素数。当然,这不会考虑ActionBar,状态栏或任何其他会减少活动本身可用大小的视图。
活动开始后,您可以执行以下操作:
View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
仅获取活动内容。但是在onCreate()中执行此操作将导致宽度和高度为0的视图。
在onCreate期间有没有办法获得这些尺寸?我想应该有一种方法可以测量任何状态栏并从总显示大小中减去它,但我无法找到一种方法。我认为这是唯一的方法,因为内容窗口方法总是在绘制之前返回没有宽度/高度的视图。
谢谢!
答案 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
视图中不显示,因此大小为零是正常的。