9

I'm wondering how to measure the dimensions of a view. In my case it is aan Absolute Layout. I've read the answers concerning those questions but I still don't get it.

This is my code:

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();     


}

The getWidth() command works great in showText() but it does not in drawOval(). I know it looks a bit different there but I also used the int x = findViewById(LAYOUT).getWidth(); version in drawOval(), and x/y are always 0. I don't really understand why there seems to be no width/height at that earlier point. Even if I actually draw a Button on the Absolute Layout, getWidth() returns 0. Oviously I want to measure the sizes in drawOval().

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
mayhem
  • 91
  • 1
  • 1
  • 2
  • 1
    Note that `AbsoluteLayout` is deprecated and should never be used. use a density-independent Layout instead! – Alex Lockwood Jan 16 '12 at 21:46
  • hi, thanks. but can I position elements absolutely in any other kind of Layout? – mayhem Jan 16 '12 at 22:14
  • No, but to design something absolutely essentially means you are designing for one screen size/density. You should be able to achieve the desired result using something like LinearLayout (for example) and density-independent unit values ("dp" or "sp" instead of "px"). – Alex Lockwood Jan 16 '12 at 22:24
  • thanks again. I just want to put colored Ovals on the screen,clickable though. Do you think to use a "normal" layout is a good idea at all? ;) maybe the best way would be to draw on a canvas?! – mayhem Jan 16 '12 at 23:02
  • oops... i thought this was more of a theoretical question about how views are drawn :). if your goal is to draw some shapes on the screen then yes, you should be creating your own custom class that extends View that can handle the work you want it to do. i'll post some samples below. – Alex Lockwood Jan 17 '12 at 00:55

6 Answers6

11

I think will help you.

   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);
    }
});


}  
Khyati Vara
  • 1,042
  • 13
  • 22
Bebin T.N
  • 2,539
  • 1
  • 24
  • 28
7

getWidth() is giving you 0 because onCreate is called before layout actually happens. Due to views being able to have dynamic positions and sizes based on attributes or other elements (fill_parent for example) there's not a fixed size for any given view or layout. At runtime there is a point in time (actually it can happen repeatedly depending on many factors) where everything is actually measured and laid out. If you really need the height and width, you'll have to get them later as you've discovered.

kabuko
  • 36,028
  • 10
  • 80
  • 93
3

This specially deal with Dimensions so

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

This may help you in managing dimensions.

Note: This returns the display dimensions in pixels - as expected. But the getWidth() and getHeight() methods are deprecated. Instead you can use:

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;

as also Martin Koubek suggested.

cristian
  • 87
  • 12
Joker
  • 715
  • 1
  • 14
  • 31
2

This give you screen resolution:

 WindowManager wm = (WindowManager)context.getSystemService(context.WINDOW_SERVICE);
 Display display = wm.getDefaultDisplay();
 Point outSize = new Point();
 display.getSize(outSize);
Martin Koubek
  • 433
  • 4
  • 8
2

If your goal is to simply draw an oval on the screen, then consider creating your own custom View rather than messing around with AbsoluteLayout. Your custom View must override onDraw(android.graphics.Canvas), which will be called when the view should render its content.

Here is some extremely simple sample code that might help get you started:

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
  • 83,063
  • 39
  • 206
  • 250
  • this [**post**](http://stackoverflow.com/questions/3616676/how-to-draw-a-line-in-android) also gives some sample code on how to draw a line if its helpful :) – Alex Lockwood Jan 17 '12 at 01:10
1

kabuko's answer is correct, but could be a little more clear, so let me clarify.

getWidth() and getHeight() are (correctly) giving you 0 because they have not been drawn in the layout when you call them. try calling the two methods on the button after addView() (after the view has been drawn and is present in the layout) and see if that gives you the expected result.

See this post for more information.

Community
  • 1
  • 1
Alex Lockwood
  • 83,063
  • 39
  • 206
  • 250
  • 1
    as i said earlier, however, i strongly suggest you use a different layout (such as `LinearLayout` or `RelativeLayout`) as `AbsoluteLayout` is **not** density-independent and will not work well across multiple screen sizes and densities. – Alex Lockwood Jan 16 '12 at 21:57
  • ...or if you are looking to draw an Oval on a Canvas, then just fill the screen with a custom-made view that can get the job done. see my code in my second answer below :) – Alex Lockwood Jan 17 '12 at 01:13