第一次重写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>

解决方案 »

  1.   

    楼主试试看用style属性是不是可以我是在xml里面设置了一个style.xml然后再在code里面setStyle就ok了
      

  2.   

    <!-- 定义my_style_button,用android的Button作为parent -->
    <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"  
         />
      

  3.   

    我没有试过自定义Button,不过我觉得既然是自适应,LZ需要执行一次onCreat()方法之后才能取得Button的长和宽。
    所以,我觉得应该在执行完onCreat()时取得长和宽然后刷新当前UI界面,把颜色填充上去。表面看是执行了一次,实际上应该是两次,刷新了一次UI界面这个思路是我在获取屏幕上方的Title栏时使用的方法,
      

  4.   

    多谢两位。
    的确在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());
    }
      

  5.   

    我觉得你学的那才叫好,哪方面都懂,看你回的很多帖子就看出来了。
    真是年轻有为啊!还有一个画文本的问题,我设置的文本是居中显示,水平方向已经搞定了,但垂直方向显示的总是偏上,而且计算出来的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);
    }
      

  6.   

    当然是由衷的赞叹,何来挖苦与讽刺啊。
    至少我觉得比我刚工作时强不知道多少倍了。
    我现在是走过了很多弯路又回来学android,真是痛心疾首。
      

  7.   

    还有个问题,就是继承Button类后,画出来的button还是带有原来button的轮廓,该怎么去掉原来的button的显示呢?
    是不是不用继承Button类,要直接继承View,完全由自己来实现?
      

  8.   

    button图片不是用.9.png图片系统自己拉伸的吗?
    tools里面有个draw9patch.bat可以制作这种格式的图片,可以在图片里面定义拉伸的位置不知道是不是这个意思呢呢
      

  9.   

    谢谢。
    我的意思是想自定义button,实现自己想要的风格。
      

  10.   

    button貌似是可以直接用style来定义的吧
      

  11.   

    应该要去掉 onDraw 中的
    super.onDraw(canvas);
    这一句,
      

  12.   

    楼主 继承button写的如何?呵呵 还希望分享下经验