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 ?
精彩评论