Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getWidth() returns 0 if set by android:layout_width="match_parent"

I have a class called FractalView that extends ImageView. My goal is to draw a fractal with this class that has the size of the whole screen. It is the only View in my activity's layout file, other than the top-level LinearLayout:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
          android:orientation="vertical"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
    android:background="#FFFFFFFF">

    <com.antonc.fractal_wallpaper.FractalView
        android:id="@+id/fractal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:visibility="gone"/>
</LinearLayout>

As you can see, I'm using "match_parent" for both layout_width and layout_height of both the FractalView and the LinearLayout. At this point I assumed that the size of the FractalView is set to a certain value, since it's matching it's parent, which is matching it's parent(which is the whole screen). Then I try to detect the size that is available to FractalView by using getWidth() and getHeight():

public class FractalView extends ImageView {

private Context mContext;
private Handler mHandler;

private int mScrWidth;
private int mScrHeight;

public FractalView(Context context) {
    super(context);
    mContext = context;
    init();
}

private void init() {

    mScrWidth = getWidth();
    mScrHeight = getHeight();
    // Breakpoint
}

@Override
protected void onDraw(Canvas canvas) {
    [...]
}

}

But when my code reaches the breakpoint, the debugger shows that mScrWidth and mScrHeight are zero. I've tried using getMeasuredWidth() and getMaxWidth(), but they also return incorrect values. I've read several answers to similar questions, i.e. this one and they all explain that getWidth() returns the size of an image after it has been drawn, while what I actually need is the width of the area which is available to this view, before I start drawing.

Is there a way to retrieve such values for width and height?

like image 377
Anton Cherkashyn Avatar asked Jan 29 '13 21:01

Anton Cherkashyn


1 Answers

A view's size isn't available until after onMeasure(), particularly if its set to wrap_content, or fill_parent.

You should either access the size in or after onMeasure() in the View code, or in a a Layout Tree Observer:

LinearLayout layout = (LinearLayout)findViewById(R.id.mylayout);
ViewTreeObserver vto = layout.getViewTreeObserver(); 
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
    @Override 
    public void onGlobalLayout() { 
        this.layout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 
        int width  = layout.getMeasuredWidth();
        int height = layout.getMeasuredHeight(); 

    } 
});

You will also need to add android:id="@+id/mylayout" to your LinearLayout for the second one to work.

like image 197
Raghav Sood Avatar answered Oct 17 '22 11:10

Raghav Sood