21

I am trying to make a simple drawing program for the android.

I have a custom View class to handle the drawing. When I call its getWidth and getHeight metheds, I get a zero.

But, the drawing works fine, I hard code in the width and height so it works. Why is it doing this?


My View class

public class cDrawing extends View{

    char BitMap[];
    static final short WIDTH=160;
    static final short HEIGHT=440;
    static final char EMPTY=' ';
    int mWidthSize;
    int mHeightSize;

    static final char RED ='R';
    int y;

    public cDrawing(Context context) {
        super(context);

        y=3;
        // set up our bitmap
        BitMap=new char[WIDTH*HEIGHT];
        for(int i=0; i<WIDTH*HEIGHT; i++)
                BitMap[i]=EMPTY;


        // returns zero why???????
        int h=getHeight();
        h=400;
        int w=getWidth();
        w=320;
        mWidthSize=w/WIDTH;
        mHeightSize=h/HEIGHT;


        // TODO Auto-generated constructor stub
    }

The Activity class

public class cCanves extends Activity  implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.canves);
        cDrawing board=new cDrawing(this);


        LinearLayout layout = (LinearLayout)findViewById(R.id.parent2);
        layout.addView(board);


        // set up buttons
        View mEraser = findViewById(R.id.buteraser);
        mEraser.setOnClickListener(this);

        View mBlack = findViewById(R.id.butblack);
        mBlack.setOnClickListener(this);

        View mWhite = findViewById(R.id.butwhite);
        mWhite.setOnClickListener(this);

        View mRed = findViewById(R.id.butred);
        mRed.setOnClickListener(this);

    } // end function

    public void onClick(View v) {
        Intent i;
        switch(v.getId())
        {
        case R.id.buteraser:
            break;
        case R.id.butblack:
            break;
        case R.id.butwhite:
            break;
        case R.id.butred:
            break;
        } // end switch

    }   // function
}

the xml file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/parent"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:orientation="vertical"
  android:layout_height="fill_parent">

    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:orientation="horizontal"
      android:layout_height="wrap_content">

    <ImageButton android:id="@+id/buteraser"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butblack"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butwhite"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butred"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
    </LinearLayout>

    <LinearLayout android:id="@+id/parent2"
      android:layout_width="fill_parent"
      android:orientation="vertical"
      android:layout_height="fill_parent">
    </LinearLayout>


</LinearLayout>
JJD
  • 50,076
  • 60
  • 203
  • 339
Ted pottel
  • 6,869
  • 21
  • 75
  • 134
  • You have to wait until your view has been instantiated and given its dimensions. Everything should be ready by the onDraw function. – Robert Massaioli May 27 '11 at 05:52
  • possible duplicate of [How do you to retrieve dimensions of a view? Getheight() and Getwidth() always return zero](http://stackoverflow.com/questions/4142090/how-do-you-to-retrieve-dimensions-of-a-view-getheight-and-getwidth-always-r) – senderle Jul 26 '12 at 10:01
  • 1
    I'll refer you to [this answer](http://stackoverflow.com/questions/4142090/how-do-you-to-retrieve-dimensions-of-a-view-getheight-and-getwidth-always-re/4406090#4406090). – Kevin Coppock May 26 '11 at 21:32

6 Answers6

19

The width and height are not defined until the view is actually rendered to the screen.

Use protected abstract void onLayout (boolean changed, int l, int t, int r, int b) (which you override in your activity) to know when the sizes are ready.

mah
  • 39,056
  • 9
  • 76
  • 93
6

Complementing Mah's answer, I found out that you can get the values from parameters, like the code bellow:

ImageView imageProcess = (ImageView) li.inflate(
    R.layout.andamento_sinistro_imageprocess, centerLayout, false);
imageProcess.setBackgroundResource(
    (isActive)?(R.drawable.shape_processon):(R.drawable.shape_processoff));
RelativeLayout.LayoutParams imageProcessParams = 
    (RelativeLayout.LayoutParams)imageProcess.getLayoutParams();
imageProcessParams.leftMargin = 
    (int) (centerPosition - 0.5*imageProcessParams.width);
imageProcessParams.addRule(RelativeLayout.CENTER_VERTICAL);
centerLayout.addView(imageProcess);

The real catch here is the use of the LayoutParams, that have rules yet not processed by the element.

JJD
  • 50,076
  • 60
  • 203
  • 339
Luiz Vianna
  • 71
  • 1
  • 1
3

I'm not certain, but it may have something to do with where the code is in the lifecycle of your activity. If you're calling getWidth() and getHeight() before the View is displayed on screen, you'll get a value of 0. I've had that happen to me, too.

I'm not sure if there's a way around this. I had to rely on getting the hardware screen's width and height, instead of the view's width and height. You might end up having to approximate the width and height of your view and hard coding it.

Jack Smartie
  • 443
  • 1
  • 5
  • 14
1

You should call getWidth() and getHeight() in the overrided method onLayout.

Ginsan
  • 344
  • 2
  • 8
0

Just Use the getViewTreeObserver() Listener, and inside this just calculate the height and width.

Follow the code :

getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //Do your Stuff calculation , like view.getWidth() ... });

-6

The view only has dimensions after beeing displayed for the first time.

Other thing:

int h=getHeight();
h=400;

Is useless no ? Is it just for testing ?

vieux
  • 23,887
  • 3
  • 26
  • 26