mobiledev Alex
mobiledev Alex

Reputation: 2318

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

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?

Upvotes: 41

Views: 35948

Answers (7)

Adorjan Princz
Adorjan Princz

Reputation: 11834

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

        ...
    }
});

Upvotes: 79

Asif Patel
Asif Patel

Reputation: 1764

Use below code:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
   super.onWindowFocusChanged(hasFocus);
   Log.e("WIDTH",""+view.getWidth());
   Log.e("HEIGHT",""+view.getHeight());
}

Upvotes: 0

Wonson
Wonson

Reputation: 610

Simpler way:

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

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

Upvotes: 3

Gene
Gene

Reputation: 11267

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

Upvotes: 1

Jeff Axelrod
Jeff Axelrod

Reputation: 28188

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

Upvotes: 38

r1k0
r1k0

Reputation: 1406

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

Upvotes: 4

MrJre
MrJre

Reputation: 7161

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.

Upvotes: 5

Related Questions