我有一个由tableelayout, TableRow和TextView组成的视图。我想让它看起来像一个网格。我需要得到这个网格的高度和宽度。方法getHeight()和getWidth()总是返回0。当我动态格式化网格和使用XML版本时,就会发生这种情况。
如何检索视图的维度?
下面是我在调试中用来检查结果的测试程序:
import android.app.Activity;
import android.os.Bundle;
import android.widget.TableLayout;
import android.widget.TextView;
public class appwig extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maindemo); //<- includes the grid called "board"
int vh = 0;
int vw = 0;
//Test-1 used the xml layout (which is displayed on the screen):
TableLayout tl = (TableLayout) findViewById(R.id.board);
tl = (TableLayout) findViewById(R.id.board);
vh = tl.getHeight(); //<- getHeight returned 0, Why?
vw = tl.getWidth(); //<- getWidth returned 0, Why?
//Test-2 used a simple dynamically generated view:
TextView tv = new TextView(this);
tv.setHeight(20);
tv.setWidth(20);
vh = tv.getHeight(); //<- getHeight returned 0, Why?
vw = tv.getWidth(); //<- getWidth returned 0, Why?
} //eof method
} //eof class
你试图得到一个元素的宽度和高度,这些元素还没有被画出来。
如果你使用调试并在某个点停止,你会看到,你的设备屏幕仍然是空的,那是因为你的元素还没有绘制,所以你不能得到宽度和高度,那还不存在。
而且,我可能是错的,但setWidth()并不总是尊重,布局布局它的孩子,并决定如何测量他们(调用child.measure()),所以如果你设置setWidth(),你不保证得到这个宽度后的元素将被绘制。
您需要的是在视图实际绘制之后的某个位置使用getMeasuredWidth()(视图的最新测量值)。
查看活动生命周期以找到最佳时刻。
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
我相信一个好的做法是这样使用OnGlobalLayoutListener:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!mMeasured) {
// Here your view is already layed out and measured for the first time
mMeasured = true; // Some optional flag to mark, that we already got the sizes
}
}
});
您可以将此代码直接放在onCreate()中,当视图被布局时,它将被调用。
你试图得到一个元素的宽度和高度,这些元素还没有被画出来。
如果你使用调试并在某个点停止,你会看到,你的设备屏幕仍然是空的,那是因为你的元素还没有绘制,所以你不能得到宽度和高度,那还不存在。
而且,我可能是错的,但setWidth()并不总是尊重,布局布局它的孩子,并决定如何测量他们(调用child.measure()),所以如果你设置setWidth(),你不保证得到这个宽度后的元素将被绘制。
您需要的是在视图实际绘制之后的某个位置使用getMeasuredWidth()(视图的最新测量值)。
查看活动生命周期以找到最佳时刻。
http://developer.android.com/reference/android/app/Activity.html#ActivityLifecycle
我相信一个好的做法是这样使用OnGlobalLayoutListener:
yourView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (!mMeasured) {
// Here your view is already layed out and measured for the first time
mMeasured = true; // Some optional flag to mark, that we already got the sizes
}
}
});
您可以将此代码直接放在onCreate()中,当视图被布局时,它将被调用。
正如F.X.提到的,你可以使用OnLayoutChangeListener来跟踪你想要跟踪的视图
view.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
@Override
public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
// Make changes
}
});
如果只需要初始布局,可以在回调中删除侦听器。