第一次重写View,有些问题不知道如何处理。请多指教!
我有个继承了Button类的类MyButton,实现一些自定义的UI效果,暂时只设置了颜色,先试验一下。
但在onDraw时不知道如何设置矩形的坐标才能显示成自适应的大小。我是先设置了一个初始值,并提供了set矩形四个坐标的函数。
我在layout中设置宽高为wrap_content,大小是可以自适应了,但我在MyButton设置的颜色大小还是我onDraw时设置的固定矩形大小。
我在activity的onCreate函数中设置MyButton的right,bottom坐标,但是不起作用。
我是用先去的MyButton的left,width,top,height的方式来计算出right和bottom的;但是去的的MyButton的left,width,top,height全是0.
这是为什么呢?是要在onCreate函数之后才能设置吗?
代码如下:
1.MyButton.java
package com.min.test;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.Button;public class MyButton extends Button {
private int mLeft = 0;
private int mTop = 0;
private int mRight = 50;
private int mBottom = 30; public MyButton(Context context) {
super(context);
}
public MyButton(Context context, int left, int top, int right, int bottom) {
super(context);
this.mLeft = left;
this.mTop = top;
this.mRight = right;
this.mBottom = bottom;
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAlpha(128);
canvas.drawRect(new RectF(mLeft, mTop, mRight, mBottom), mPaint);
Log.i("MyButton", "======================================");
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyDown(keyCode, event);
} @Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyUp(keyCode, event);
} @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
} public int getMLeft() {
return mLeft;
} public void setMLeft(int left) {
mLeft = left;
} public int getMTop() {
return mTop;
} public void setMTop(int top) {
mTop = top;
} public int getMRight() {
return mRight;
} public void setMRight(int right) {
mRight = right;
} public int getMBottom() {
return mBottom;
} public void setMBottom(int bottom) {
mBottom = bottom;
}
}
2.AndroidTest.java
public class AndroidTest extends Activity {
private final String TAG = "AndroidTest";
private Context context;
private MyButton mMyBtnSayHello, mMyBtnClickMe;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.main);
// GameSurfaceView gameSurfaceView = new GameSurfaceView(this);
// gameSurfaceView.Draw();
mMyBtnSayHello = (MyButton)findViewById(R.id.btn_say_hello);
mMyBtnClickMe = (MyButton)findViewById(R.id.btn_click_me);
int right = mMyBtnSayHello.getMLeft() + mMyBtnSayHello.getWidth();
int height = mMyBtnSayHello.getMTop() + mMyBtnSayHello.getHeight();
mMyBtnSayHello.setMRight(right);
mMyBtnSayHello.setMBottom(height);
mMyBtnSayHello.invalidate(); mMyBtnClickMe.setMRight(mMyBtnClickMe.getMLeft() + mMyBtnClickMe.getWidth());
mMyBtnClickMe.setMBottom(mMyBtnClickMe.getMTop() + mMyBtnClickMe.getHeight());
mMyBtnClickMe.invalidate();
Log.i(TAG, "onCreate end...");
}
3.main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.min.test.MyButton
android:id="@+id/btn_say_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say Hello"
/>
<com.min.test.MyButton
android:id="@+id/btn_click_me"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
/>
</LinearLayout>
我有个继承了Button类的类MyButton,实现一些自定义的UI效果,暂时只设置了颜色,先试验一下。
但在onDraw时不知道如何设置矩形的坐标才能显示成自适应的大小。我是先设置了一个初始值,并提供了set矩形四个坐标的函数。
我在layout中设置宽高为wrap_content,大小是可以自适应了,但我在MyButton设置的颜色大小还是我onDraw时设置的固定矩形大小。
我在activity的onCreate函数中设置MyButton的right,bottom坐标,但是不起作用。
我是用先去的MyButton的left,width,top,height的方式来计算出right和bottom的;但是去的的MyButton的left,width,top,height全是0.
这是为什么呢?是要在onCreate函数之后才能设置吗?
代码如下:
1.MyButton.java
package com.min.test;import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.widget.Button;public class MyButton extends Button {
private int mLeft = 0;
private int mTop = 0;
private int mRight = 50;
private int mBottom = 30; public MyButton(Context context) {
super(context);
}
public MyButton(Context context, int left, int top, int right, int bottom) {
super(context);
this.mLeft = left;
this.mTop = top;
this.mRight = right;
this.mBottom = bottom;
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyButton(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAlpha(128);
canvas.drawRect(new RectF(mLeft, mTop, mRight, mBottom), mPaint);
Log.i("MyButton", "======================================");
} @Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyDown(keyCode, event);
} @Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
// TODO Auto-generated method stub
return super.onKeyUp(keyCode, event);
} @Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
return super.onTouchEvent(event);
} public int getMLeft() {
return mLeft;
} public void setMLeft(int left) {
mLeft = left;
} public int getMTop() {
return mTop;
} public void setMTop(int top) {
mTop = top;
} public int getMRight() {
return mRight;
} public void setMRight(int right) {
mRight = right;
} public int getMBottom() {
return mBottom;
} public void setMBottom(int bottom) {
mBottom = bottom;
}
}
2.AndroidTest.java
public class AndroidTest extends Activity {
private final String TAG = "AndroidTest";
private Context context;
private MyButton mMyBtnSayHello, mMyBtnClickMe;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
context = this;
setContentView(R.layout.main);
// GameSurfaceView gameSurfaceView = new GameSurfaceView(this);
// gameSurfaceView.Draw();
mMyBtnSayHello = (MyButton)findViewById(R.id.btn_say_hello);
mMyBtnClickMe = (MyButton)findViewById(R.id.btn_click_me);
int right = mMyBtnSayHello.getMLeft() + mMyBtnSayHello.getWidth();
int height = mMyBtnSayHello.getMTop() + mMyBtnSayHello.getHeight();
mMyBtnSayHello.setMRight(right);
mMyBtnSayHello.setMBottom(height);
mMyBtnSayHello.invalidate(); mMyBtnClickMe.setMRight(mMyBtnClickMe.getMLeft() + mMyBtnClickMe.getWidth());
mMyBtnClickMe.setMBottom(mMyBtnClickMe.getMTop() + mMyBtnClickMe.getHeight());
mMyBtnClickMe.invalidate();
Log.i(TAG, "onCreate end...");
}
3.main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<com.min.test.MyButton
android:id="@+id/btn_say_hello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Say Hello"
/>
<com.min.test.MyButton
android:id="@+id/btn_click_me"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click Me"
/>
</LinearLayout>
<style name="my_style_button" parent="@android:style/Widget.Button">
<!-- 定义与指定View相关的若干属性 -->
<item name="android:hint">"load from style my button"</item>
<item name="android:textColorHint">#ff1200</item>
<item name="android:textSize">20sp</item>
<item name="android:textStyle">bold|italic</item>
<item name="android:textColor">#FF00FF</item>
<item name="android:textColorHighlight">#cccccc</item>
<item name="android:typeface">monospace</item>
<item name="android:background">@drawable/button_normal</item>
</style>我设置了一个button的style,但是怎么实现圆角啊?还有就是我在layout中把宽度,高度设置为自适应,但button的宽度很宽,远远超过字符串的宽度,接近但还不到屏幕宽度。
这是为什么呢?
<Button
android:id="@+id/btn_test"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/my_style_button"
android:text="Test Only"
/>
所以,我觉得应该在执行完onCreat()时取得长和宽然后刷新当前UI界面,把颜色填充上去。表面看是执行了一次,实际上应该是两次,刷新了一次UI界面这个思路是我在获取屏幕上方的Title栏时使用的方法,
的确在onCreate里面还得不到控件的宽高值,在onDraw的时候才能得到。
不需要用上面的方法,直接在MyButton的onDraw函数中用getWidth(), getHeight()就可以取得MyButton的宽和高,然后设置为矩形的right和bottom参数就可以了。
即
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Paint mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setAlpha(128);
canvas.drawRect(new RectF(0, 0, getWidth(), getHeight()), mPaint);
Log.i("MyButton", "==== onDraw(Canvas) ====");
Log.i(TAG, "width = " + getWidth() + ", height = " + getHeight());
}
真是年轻有为啊!还有一个画文本的问题,我设置的文本是居中显示,水平方向已经搞定了,但垂直方向显示的总是偏上,而且计算出来的drawText的y坐标也是对的,但画出来后就偏上。难道说drawText的x,y坐标不是文本左上角的位置?@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
Log.i("MyButton", "==== onDraw(Canvas) ====");
int left, top, right, bottom;
left = MARGIN;
top = MARGIN;
right = getWidth() - MARGIN;
bottom = getHeight() - MARGIN;
Paint mPaint = new Paint();
if (this.hasFocus() || this.isPressed()) {
mPaint.setColor(Color.BLUE);
Log.i("MyButton", "Set color to BLUE.");
} else {
mPaint.setColor(Color.GRAY);
Log.i("MyButton", "Set color to GRAY.");
}
Log.i(TAG, "width = " + getWidth() + ", height = " + getHeight());
// mPaint.setAlpha(128);
canvas.drawRect(new RectF(left, top, right, bottom), mPaint);
// set text color
mPaint.setColor(Color.BLACK);
mPaint.setTextSize(16); // FontMetrics对象
FontMetrics fontMetrics = mPaint.getFontMetrics();
// draw text
float x = (getWidth() - mPaint.measureText(getText().toString())) / 2;
float y = (getHeight() - mPaint.getTextSize()) / 2;
Log.i(TAG, "mPaint.getTextSize() = " + mPaint.getTextSize() + ", getHeight() = " + getHeight());
Log.i(TAG, "x = " + x + ", y = " + y);
canvas.drawText(getText().toString(), x, y, mPaint);
}
至少我觉得比我刚工作时强不知道多少倍了。
我现在是走过了很多弯路又回来学android,真是痛心疾首。
是不是不用继承Button类,要直接继承View,完全由自己来实现?
tools里面有个draw9patch.bat可以制作这种格式的图片,可以在图片里面定义拉伸的位置不知道是不是这个意思呢呢
我的意思是想自定义button,实现自己想要的风格。
super.onDraw(canvas);
这一句,