3

I'm an Android newbie. This should be the easiest thing in the world, but figuring it out is driving me batty: how do I get the dimensions of a view or layout?

The standard approach seems to be something along the lines of:

((LinearLayout)this.findViewById(R.id.MyLayout)).getWidth();

Except that this always returns zero, since I'm trying to do this when the Activity starts up (onCreate) and the geometry isn't set yet. I tried putting in sleeps to give it a chance to set up the layout, except that it won't set up the layout until onCreate returns. So it's clearly not threaded. :P

I found a bunch of pages talking about overriding all sorts of different callback functions in order to be sure that the layout is loaded when you call getWidth -- but all of them threw errors when I tried to put the overrides in my Activity. So I can assume that they were callbacks for the layouts and/or views being measured. The problem with that is that I'm not using custom view/layout classes -- just the standard ones. So I can't just add an override, as far as I know.

Anyone know what I should do? I've spent something like 8 hours on this problem and gotten nowhere. And it's something that's normally such a trivial thing to do in most development environments!

KarenRei
  • 589
  • 6
  • 13

5 Answers5

22
final View view = .....; // your view

view.getViewTreeObserver().addOnGlobalLayoutListener(
    new ViewTreeObserver.OnGlobalLayoutListener() {

      @Override
      public void onGlobalLayout() {
        // make sure it is not called anymore 
        view.getViewTreeObserver().removeGlobalOnLayoutListener(this);

        // your code to get dimensions of the view here:
        // ...
      }
    });
plugmind
  • 7,926
  • 4
  • 34
  • 39
  • Interesting. But it's not working for me. "The method onGlobalLayout of type new ViewTreeObserver.OnGlobalLayoutListener(){} must override a superclass method" Thoughts? – KarenRei Aug 28 '10 at 03:18
  • Make sure all neccessary interfaces and classes are imported. – plugmind Aug 29 '10 at 12:01
  • Thank you very much, it works for me, and I think it better than using onWindowFocusChanged ! – Tim Autin Mar 22 '13 at 19:38
  • It's worked, thanks. But removeGlobalOnLayoutListener is deprecated. I used removeOnGlobalLayoutListener. – Mete Aug 14 '20 at 13:37
1

Two years late, but putting it here for others. Try overriding onWindowFocusChanged. You should be able to get the measured width/height of the view in there.

PacificSky
  • 3,422
  • 2
  • 25
  • 24
1

Why not View.getLayoutParams()? It has public int height and public int width.

Tyler
  • 19,113
  • 19
  • 94
  • 151
0

How about doing it durring onStart()? This method is called after onCreate() has finished executing, meaning the layout has been inflated. android lifecycle

smith324
  • 13,020
  • 9
  • 37
  • 58
  • Thanks! Unfortunately, it didn't seem to work -- it still returns zero. And this is being called on the main layout of the app defined in the xml file, which is set to fill_parent for both width and height. Any other hypotheses? – KarenRei Aug 27 '10 at 07:07
  • As a followup, I put a sleep so I could see what the screen looked like on onStart. It was all black, nothing drawn. I also tried onResume, but it still was black there, too. – KarenRei Aug 27 '10 at 07:12
  • One more followup: I tried one more technique -- getLayoutParams() in onStart. It says the width is "-1". :P – KarenRei Aug 27 '10 at 07:26
-1

I have a work-around where I use:

view.postDelayed(new MyRunnable(), 500); 

which runs the logic in MyRunnable 500 ms from now. This allows onCreate or whatever lifecycle method to return and drawing to occur so that I can get the correct height and width. But it is also ugly as the user can see the delay.

George Stocker
  • 57,289
  • 29
  • 176
  • 237
Nathan
  • 1