Android 在onCreate中获取内容视图大小
我正在寻找一种很好的方法来测量Android中活动的实际内容区域的维度 获取显示总是有效的。简单地说:Android 在onCreate中获取内容视图大小,android,Android,我正在寻找一种很好的方法来测量Android中活动的实际内容区域的维度 获取显示总是有效的。简单地说: Display display = getWindowManager().getDefaultDisplay(); 你可以得到整个屏幕的像素数。当然,这并没有考虑操作栏、状态栏或任何其他视图,这些视图会减少活动本身的可用大小 活动运行后,您可以执行以下操作: View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
Display display = getWindowManager().getDefaultDisplay();
你可以得到整个屏幕的像素数。当然,这并没有考虑操作栏、状态栏或任何其他视图,这些视图会减少活动本身的可用大小
活动运行后,您可以执行以下操作:
View content = getWindow().findViewById(Window.ID_ANDROID_CONTENT);
仅获取活动内容。但在onCreate()中执行此操作将生成宽度和高度为0,0的视图
是否有办法在onCreate期间获取这些维度?我想应该有一种方法来获得任何状态栏的测量值,然后从总显示大小中减去它,但我找不到一种方法来做到这一点。我认为这是唯一的方法,因为contentwindow方法在绘制之前总是返回一个没有宽度/高度的视图
谢谢 您可以在
onResume
中完成任何需要大小的工作(使用类似alreadyDone
的标志,不要在每次活动
进入前台时重复)。在onCreate中,视图不显示,因此大小为零是正常的。根据您的目标,您可以使用布局或预绘制侦听器进行此操作。例如,在onCreate()中:
更新
从API 16开始,RemoveGlobalOnlyOutliner
已被弃用
改为:
content.getViewTreeObserver().removeOnGlobalLayoutListener(此)
(复制自)
我使用以下技术-发布一个runnable fromonCreate()
,创建视图时将执行该操作:
contentView = findViewById(android.R.id.content);
contentView.post(new Runnable()
{
public void run()
{
contentHeight = contentView.getHeight();
}
});
在
onCreate()
完成后,此代码将在主UI线程上运行。这似乎是一个重复的问题。这个问题有一个优雅的答案:
其中(厚颜无耻地复制)将覆盖onWindowFocusChanged(),它似乎在onCreate()之后触发,并且在其中呈现大小:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
//Here you can get the size!
}
如果要将位图加载到
OnCreate()
中的ImageView
中,可以使用以下示例:
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);
}
});
}
使用
post
回答不正确,因为可能无法重新计算大小。另一件重要的事情是视图及其所有祖先必须可见。为此,我使用了一个属性
View.isShown
这是我的kotlin函数,可以放在UTIL中的某个位置:
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)
}
检查此项,这可能有助于窗口可能没有在onCreate中绘制,这就是为什么得到0,0的原因。我建议您将代码移动到onStart,以便至少绘制视图。我尝试将“创建”、“开始”和“恢复”中的内容作为测试获取,但所有3个都返回了0,0。不过值得一试。我发现在onResume中的视图也是0,0。这很有效,谢谢。我只是希望有一种方法可以在没有听众的情况下做到这一点,但不管怎样。你可能可以。取决于您打算如何处理此信息。如果内容视图本身需要了解其大小,请创建一个自定义视图组,并覆盖
onLayout
。在这一点上,你将知道你的宽度和高度。@blabus实际上不是,这是一个API打字错误。不过,他们确实在API 16中添加了一个正确的版本。还有其他方法可以获得视图大小吗?我必须用视图宽度初始化animator。在API 16+中,您应该使用RemoveOnGlobalYoutListener()
而不是RemoveGlobalOnlayOutliner()
。与其说是对的,不如说是拙劣的。这将触发一系列事件,比如当你得到一个对话框或者基本上任何改变窗口焦点的事情时。使用预绘制的侦听器似乎更好。是的,很公平。我可能应该说“短”而不是“优雅”。KCopock的答案更优雅,但对于一个简单的问题来说,它更像是废话。但它确实是高效和正确的。看起来预绘制比布局更好,它非常明确地正确。“在即将绘制视图树时调用的回调方法。此时,树中的所有视图都已测量并给定了一个框架。客户端可以使用此方法调整其滚动边界,甚至在绘制之前请求新布局。”效果很好。。谢谢:)
myView.onInitialized {
Log.d(TAG, "width is: " + myView.width)
}