在Android中获取布局的宽度/高度

9
我想知道如何测量视图的尺寸。在我的情况下,它是一个绝对布局。我已经阅读了有关这些问题的答案,但仍然不理解。

这是我的代码:

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main);      

    AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);       

    drawOval(); 

}
public void drawOval(){ //, int screenWidth, int screenHeight){ 
    AbsoluteLayout layoutbase = (AbsoluteLayout) findViewById(R.id.layoutbase);     

    int screenWidth = layoutbase.getWidth();
    int screenHeight = layoutbase.getHeight();
    Log.i("MyActivity", "screenWidth: " + screenWidth + ", screenHeight: " +screenHeight);

    Coordinates c = new Coordinates(BUTTONSIZE,screenWidth,screenHeight);

    ...some code ...

    ((ViewGroup) layoutbase ).addView(mybutton, new AbsoluteLayout.LayoutParams(BUTTONSIZE, BUTTONSIZE, c.mX, c.mY));


    mybutton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            showText(mybutton);
        }
    });
}

public void showText(View button){      

    int x = findViewById(LAYOUT).getWidth();
    int y = findViewById(LAYOUT).getHeight(); 

    Toast message = Toast.makeText(this, "x: " + x , Toast.LENGTH_SHORT);       
    message.show();     


}
getWidth()命令在showText()中效果很好,但在drawOval()中却不起作用。我知道它在那里看起来有点不同,但我也在drawOval()中使用了int x = findViewById(LAYOUT).getWidth();版本,而且x/y始终是0。我真的不明白为什么在早期没有宽度/高度。即使我在绝对布局上实际画一个按钮,getWidth()也会返回0。显然,我想在drawOval()中测量大小。

1
请注意,AbsoluteLayout已被弃用,不应再使用。请改用密度无关的布局! - Alex Lockwood
嗨,谢谢。但是我可以在任何其他类型的布局中绝对定位元素吗? - mayhem
不,但是设计某物绝对基本上意味着你正在为一个屏幕尺寸/密度进行设计。您应该能够使用诸如LinearLayout(例如)和密度无关的单位值(“dp”或“sp”而不是“px”)来实现所需的结果。 - Alex Lockwood
再次感谢。我只想在屏幕上放置有颜色的椭圆形,但可点击。您认为使用“普通”布局是个好主意吗? ;) 或许最好的方法是在画布上绘制?! - mayhem
哎呀...我以为这更多是一个关于视图如何绘制的理论问题 :). 如果你的目标是在屏幕上绘制一些形状,那么是的,你应该创建自己的自定义类,它扩展了View并且可以处理你想要它做的工作。我会在下面发布一些示例。 - Alex Lockwood
6个回答

11

我认为这会对你有所帮助。

   LinearLayout headerLayout = (LinearLayout)findviewbyid(R.id.headerLayout);
    ViewTreeObserver observer = headerLayout .getViewTreeObserver();
            observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

        @Override
        public void onGlobalLayout() {
            // TODO Auto-generated method stub
            int headerLayoutHeight= headerLayout.getHeight();
        int headerLayoutWidth = headerLayout.getWidth();
        headerLayout .getViewTreeObserver().removeGlobalOnLayoutListener(
                this);
    }
});


}  

在您的情况下,“l”是什么?l.getHeight() - nutella_eater

7

getWidth() 返回 0 是因为在布局实际发生之前调用了 onCreate。由于视图可以根据属性或其他元素(例如`fill_parent`)具有动态位置和大小,因此任何给定视图或布局都没有固定的大小。在运行时,实际上可以测量和布局所有内容的时间点(实际上可以根据许多因素反复发生)。如果您真的需要高度和宽度,则必须稍后获取它们,就像您所发现的那样。


3

这里特别涉及到 维度(Dimension),因此

Display display = getWindowManager().getDefaultDisplay(); 
int width = display.getWidth(); 
int height = display.getHeight();

这可能会帮助您管理尺寸。
注意:此处返回的是预期的以像素为单位的显示尺寸。但是getWidth()和getHeight()方法已被弃用。相反,您可以使用以下方法:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

正如Martin Koubek所建议的那样。

2
如果您的目标只是在屏幕上绘制一个椭圆形,那么考虑创建自己的自定义View而不是混乱地使用AbsoluteLayout。您的自定义View必须重写onDraw(android.graphics.Canvas),当视图渲染其内容时将调用该方法。
以下是一些非常简单的示例代码,可能有助于您入门:
public class MainActivity extends Activity {

    private final Paint mPaint = new Paint();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new SampleView(this));
    }

    // create a nested custom view class that can draw an oval. if the
    // "SampleView" is not specific to the Activity, put the class in 
    // a new file called "SampleView.java" and make the class public 
    // and non-static so that other Activities can use it. 
    private static class SampleView extends View {
        public SampleView(Context context) {
            super(context);
            setFocusable(true);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(Color.CYAN);

            // smoothen edges
            mPaint.setAntiAlias(true);
            mPaint.setColor(Color.RED);
            mPaint.setStyle(Paint.Style.STROKE); 
            mPaint.setStrokeWidth(4.5f);

            // set alpha value (opacity)
            mPaint.setAlpha(0x80);

            // draw oval on canvas
            canvas.drawOval(new RectF(50, 50, 20, 40), mPaint);
        }
    }
}

这个帖子还提供了一些绘制线条的示例代码,如果有帮助的话 :) - Alex Lockwood

2

这将为您提供屏幕分辨率:

 WindowManager wm = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
 Display display = wm.getDefaultDisplay();
 Point outSize = new Point();
 display.getSize(outSize);

int width = size.x; int height = size.y; 宽度为size.x; 高度为size.y; - CoolMind

1
kabuko的回答是正确的,但可能需要更清晰一些,让我来澄清一下。
getWidth()和getHeight()之所以返回0,是因为在调用它们时还没有在布局中绘制。尝试在addView()之后(视图已被绘制并存在于布局中)在按钮上调用这两个方法,看看是否得到了预期的结果。
有关更多信息,请参见此帖子

1
正如我之前所说,我强烈建议您使用不同的布局(例如LinearLayoutRelativeLayout),因为AbsoluteLayout不是密度无关的,并且在多个屏幕尺寸和密度上效果不佳。 - Alex Lockwood
如果你想在画布上画一个椭圆形,那么只需用一个自定义视图来填充屏幕即可完成任务。请查看下面我的第二个回答中的代码 :) - Alex Lockwood

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接