开发者

getWidth and getHeight are returning a zero

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>


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.


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.


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.


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


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


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 ?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜