If I call getMeasuredWidth() or getWidth() for layout in onResume they return 0
Asked Answered
T

7

41

If I call getMeasuredWidth() or getWidth() for layout in onResume they returns 0. I think that view it's not drawn yet in this moment.

Also I think that I need to put getMeasuredWidth() or getWidth() in callback method called after layout is drawn and view measurements are known. What android callback method should I use?

Televisor answered 4/8, 2011 at 9:26 Comment(0)
H
79

You cannot use the width/height/getMeasuredWidth/getMeasuredHeight on a View before the system renders it (typically from onCreate/onResume).

Simple solution for this is to post a Runnable to the layout. The runnable will be executed after the View has been laid out.

BoxesLayout = (RelativeLayout) findViewById(R.id.BoxesLinearLayout);
BoxesLayout.post(new Runnable() {
    @Override
    public void run() {
        int w = BoxesLayout.getMeasuredWidth();
        int h = BoxesLayout.getMeasuredHeight();

        ...
    }
});
Hydrosol answered 20/1, 2013 at 14:27 Comment(5)
I've always used the ViewTreeObserver approach, but this is so much simpler!Graham
Way better than the ViewTreeObserver methodInterfere
The ViewTreeObserver is a better method because you can get the measure of the width/height BEFORE your view hierarchy gets drawn into the screen. If you use .post() like this the view might draw a frame first and then your callback will be called. If you are modifying some of your views width/height inside your Runnable, you can see the quick flicker of the change happening. With ViewTreeObserver you are guaranteed you can modify whatever you want BEFORE your screen draws the first frame. If you do not modified any views inside your Runnable, however, then both methods should work fine.Turbary
I tried with ViewTreeObserver and also with .post but no luck... reccyclerView width is still 0, any idea why ? I use data binding and need the width to do some calculation but it's alway 0 whatever I try but it show correctly with full widthMali
There're extension functions in Kotlin which could help you to get width/height of a View: doOnLayout() or doOnNextLayout(). There's also doOnPreDraw() available as well :)Fondly
C
38

This answer says:

Use the ViewTreeObserver on the View to wait for the first layout. Only after the first layout will getWidth()/getHeight()/getMeasuredWidth()/getMeasuredHeight() work.

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
if (viewTreeObserver.isAlive()) {
  viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
      view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
      viewWidth = mediaGallery.getWidth();
      viewHeight = mediaGallery.getHeight();
    }
  });
}
Cavallaro answered 29/7, 2012 at 15:28 Comment(2)
I'm surprised that hooking into any of the lifecycle callbacks doesn't work with getting the width. I tried all of them, onCreate(), onStart(), onResume(), and the width of the layout was not set in any of them. This solution was the first thing that worked for me. Thanks for posting.Holstein
Oh, and removeGlobalOnLayoutListener is now deprecated. The API says to use removeOnGlobalLayoutListener instead (developer.android.com/reference/android/view/…) for targeted APIs 16 and newerHolstein
B
5

you can override onLayout() in your view; this is used by android to position each of the children the view has, so you could do the stuff you want to do there after the super(..) call.

Busse answered 4/8, 2011 at 9:35 Comment(0)
H
4

Indeed, it appears that if the layout is not shown on the screen the getWidth() method returns 0. What seems to work for me is calling the measure() method before calling the getMeasuredWidth() or getMesuredHeight(). For the measure method I used the Layout.WRAP_CONTENT arguments to get a measurement of what the layout contains.

Hope this helps, Mihai

Hardball answered 13/2, 2012 at 10:58 Comment(0)
B
3

Simpler way:

view.post(new Runnable() {
    public void run() {
        view.getWidth();
    }
}
);

http://developer.android.com/reference/android/view/View.html#post(java.lang.Runnable)

Barragan answered 28/7, 2015 at 13:55 Comment(0)
M
1

Solution #1: To do it dynamically, you need a tag. A tag is basically a way for views to have memories. So save the convertView in another class (MyTag). So inside your java file:

private LayoutInflater layoutInflater;

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    MyTag holder = null;
    View row = convertView;
    if (row == null) {
      //Inflate the view however u can  
String strInflater = Context.LAYOUT_INFLATER_SERVICE;
        layoutInflater = (LayoutInflater) context.getSystemService(strInflater);
        LayoutInflater inflater = ((Activity) context).getLayoutInflater();
        row = inflater.inflate(layoutResID, parent, false);
               holder = new MyTag();

            holder.itemName = (TextView) row.findViewById(R.id.example_itemname);
            holder.icon = (ImageView) row.findViewById(R.id.example_image);
            holder.button1 = (Button) row.findViewById(R.id.swipe_button1);
            holder.button2 = (Button) row.findViewById(R.id.swipe_button2);
            holder.button3 = (Button) row.findViewById(R.id.swipe_button3);
            row.setTag(holder);
        } else {
            holder = (MyTag) row.getTag();
        }

        holder.itemName.setText(itemdata.getItemName());
        System.out.println("holder.button3.getMeasuredWidth()= "+ holder.button3.getMeasuredWidth());
        System.out.println("holder.button3.getWidth()= "+ holder.button3.getWidth());

return row;
} //End of getView()


static class MyTag {  //It also works if not static

        TextView itemName;
        ImageView icon;
        Button button1;
        Button button2;
        Button button3;
    }

Solution #2: Hard-code it. Pre-set the width. Inside your res/values/dimens.xml file, include

<dimen name="your_button_width">50dp</dimen>

Then inside your res/layout/your_layout.xml file, include

        <Button  
         android:layout_width="@dimen/your_button_width"  />

Then inside your java file:

int buttonSize= (int) (context.getResources().getDimension(R.dimen.your_button_width));
Mel answered 12/12, 2014 at 22:52 Comment(0)
A
0

Use below code:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   Log.e("WIDTH",""+view.getWidth());
   Log.e("HEIGHT",""+view.getHeight());
}
Arnica answered 10/2, 2017 at 20:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.