getHeight 为所有 Android UI 对象返回 0
Posted
技术标签:
【中文标题】getHeight 为所有 Android UI 对象返回 0【英文标题】:getHeight returns 0 for all Android UI objects 【发布时间】:2011-12-31 12:54:34 【问题描述】:我正在构建一个 UI,它在 XML 中都是静态定义的。所有的东西都有重量,虽然它看起来不错,但我想看看这些东西实际上有正确的高度等等。问题是,无论我在哪里为格式布局调用 .getHeight(),我都得到了 0。我在 onCreate() 和 onStart() 中都进行了尝试。一样。也适用于所有 UI 对象。有什么想法吗?
package com.app.conekta;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.Toast;
public class Conekta extends Activity
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
@Override
public void onStart()
super.onStart();
@Override
public void onResume()
super.onResume();
FrameLayout fl1 = (FrameLayout) findViewById(R.id.headerFrameLayout);
FrameLayout fl2 = (FrameLayout) findViewById(R.id.footerFrameLayout);
Button b=(Button) findViewById(R.id.searchButton);
Log.d("CONEKTA", String.valueOf(b.getHeight()));
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<FrameLayout
android:id="@+id/headerFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.05"
android:background="#597eAA" >
<ImageView
android:id="@+id/logoImage"
android:layout_
android:layout_
android:background="#7ba1d1"
android:src="@drawable/logo_conekta" />
</FrameLayout>
<LinearLayout
android:id="@+id/bodyLinearLayout"
android:layout_
android:layout_
android:layout_weight="0.7"
android:background="#f3f3f3"
android:orientation="horizontal" >
<FrameLayout
android:id="@+id/leftBlankFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.15"
android:background="#f3f3f3" >
</FrameLayout>
<LinearLayout
android:id="@+id/centerVerticalLayout"
android:layout_
android:layout_
android:layout_weight="0.7"
android:orientation="vertical" >
<FrameLayout
android:id="@+id/topCenterFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.35" >
</FrameLayout>
<TextView
android:id="@+id/venueLabel"
android:layout_
android:layout_
android:layout_weight="0.025"
android:text="What are you looking for?"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000" />
<EditText
android:id="@+id/venueTextField"
android:layout_
android:layout_
android:layout_weight="0.025" >
<requestFocus />
</EditText>
<FrameLayout
android:id="@+id/middleCenterFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.05" >
</FrameLayout>
<TextView
android:id="@+id/locationLabel"
android:layout_
android:layout_
android:layout_weight="0.025"
android:text="Where?"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="#000000" />
<AutoCompleteTextView
android:id="@+id/locationTextField"
android:layout_
android:layout_
android:layout_weight="0.025"
android:text="" />
<LinearLayout
android:id="@+id/buttonLinearLayout"
android:layout_
android:layout_
android:layout_weight="0.05"
android:background="#f3f3f3"
android:orientation="horizontal" >
<FrameLayout
android:id="@+id/leftButtonLinearLayout"
android:layout_
android:layout_
android:layout_weight="0.1" >
</FrameLayout>
<Button
android:id="@+id/searchButton"
android:layout_
android:layout_
android:layout_weight="0.8"
android:background="#6fa8dc"
android:text="Search" />
<FrameLayout
android:id="@+id/rightButtonLinearLayout"
android:layout_
android:layout_
android:layout_weight="0.1" >
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/bottomCenterFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.35" >
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/rightBlankFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.15"
android:background="#f3f3f3" >
</FrameLayout>
</LinearLayout>
<FrameLayout
android:id="@+id/footerFrameLayout"
android:layout_
android:layout_
android:layout_weight="0.15"
android:background="#7ba1d1" >
</FrameLayout>
</LinearLayout>
【问题讨论】:
getWidth() and getHeight() of View returns 0的可能重复 【参考方案1】:它是 0,因为在 onCreate 和 onStart 中,实际上还没有绘制视图。您可以通过侦听实际绘制视图的时间来解决此问题:
final TextView tv = (TextView)findViewById(R.id.venueLabel);
final ViewTreeObserver observer= tv.getViewTreeObserver();
observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
tv.getHeight()
observer.removeGlobalOnLayoutListener(this);
);
删除监听器的调用是为了防止在布局更改时重复调用您的自定义处理程序...如果您想获得这些,可以省略它。
【讨论】:
这应该在哪个Activity生命周期方法中实现?我仍然为 tv.getHeight() 得到 0 @IgorGanapolsky,此方法适用于我在 onCreateView 中的片段。对于正常的活动,我希望 onCreate 是合适的。removeGlobalOnLayoutListener
现在已弃用,您应该改用removeOnGlobalLayoutListener
。
在致电removeGlobalOnLayoutListener
之前最好检查observer.isAlive()
或查看***.com/questions/26192686/…
这是有效的,但如果我想以编程方式同时创建多个视图并知道其他人的维度(尽管我正在给出维度),这将不符合我的目的。【参考方案2】:
简而言之,视图尚未在 onCreate()、onStart() 或 onResume() 中构建。由于它们在技术上不存在(就 ViewGroup 而言),它们的尺寸为 0。
总之,您可以到这里获得有关如何处理它的更好解释。
How to retrieve the dimensions of a view?
【讨论】:
【参考方案3】:使用此函数获取视图的高度或宽度
private int getHeightOfView(View contentview)
contentview.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
//contentview.getMeasuredWidth();
return contentview.getMeasuredHeight();
【讨论】:
最佳答案 它没有回答我【参考方案4】:我再次回答这个问题是为了确保像我这样的人在实施之前能够完全理解它是如何工作的。
问。为什么我的视图高度为 0?A. 因为您尝试获取的视图高度尚未内置于 onCreate()、onStart() 或onResume()。
问。现在我应该在哪里以及如何获取视图的高度?A. 您仍然可以在任何您想要的地方获取视图的参数,例如 onCreate()、onStart()、或 onResume()。如下:
@Override
protected void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
TextView tv = (TextView)findViewById(R.id.textview1);
ViewTreeObserver viewTreeObserver = tv.getViewTreeObserver();
if (viewTreeObserver.isAlive())
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
viewHeight = tv.getHeight();
);
不过,这一次您将等到获得视图的高度后再移除观察者。
tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
问。那么在删除此侦听器之前我应该检查什么? **A.**在删除 treeObserver 之前添加一个 if 条件,例如,
if (viewHeight != 0)
tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
最终代码:
ViewTreeObserver viewTreeObserver = tv.getViewTreeObserver();
if (viewTreeObserver.isAlive())
viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener()
@Override
public void onGlobalLayout()
int viewHeight = tv.getHeight();
if (viewHeight != 0)
tv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
);
希望这能解释为什么 getHeight 返回 0 以及如何正确获取它。 谢谢。
【讨论】:
感谢您的详细解答。但是有必要去掉 OnGlobalLayoutListener 吗?例如,如果每次视图大小发生变化时我都需要做某事 不,没有必要,只有当您想在每次更改视图大小时执行任务时。但是请确保在完成后删除侦听器,并且您不再需要收听它。 顺便说一句,我删除了if (viewTreeObserver.isAlive())
它仍然可以按预期工作。【参考方案5】:
通过在视图中获取按钮,您可以轻松获取其高度等。
您可以像这样定义onClickListener
:
Button b=(Button) findViewById(R.id.searchButton);
b.setOnClickListener(ButtonClick);
android.view.View.OnClickListener ButtonClick= new android.view.View.OnClickListener()
public void onClick(View v)
v.getHeight();
;
希望这会有所帮助。
【讨论】:
【参考方案6】:我遇到过这个问题,鉴于没有人提到这个解决方案,我觉得分享一下很有用。
你可以@Override
onSizeChange
方法,我猜这发生在通货膨胀过程中。
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
super.onSizeChanged(w, h, oldw, oldh);
getDimensions();
其中getDimensions()
是您的自定义View
的一个方法,您可以在其中调用getHeight
和getWidth
并分配给您的类字段并根据需要重新设置。
【讨论】:
以上是关于getHeight 为所有 Android UI 对象返回 0的主要内容,如果未能解决你的问题,请参考以下文章
错误 - 尝试在空对象引用上调用虚拟方法“int android.graphics.Bitmap.getHeight()”
getWidth() 和 getHeight 在 onMeasure() 之后返回零(特定设备)
bitmap.getWidth()或bitmap.getHeight()的单位是多少