如何在EditText中嵌入一个Button

来源:互联网 发布:西安临潼网络花店 编辑:程序博客网 时间:2024/06/05 09:22

有很多人希望能在一个EditText中嵌入一个Button,用作搜索、清除等作用。但是EditText并不是一个ViewGroup,所以,要实现在EditText中嵌入一个Button,并不是一个非常简单的事情,当然,也不是太复杂。 :)

下面我给一个最简单的方案,当然,这个方案可以继续完善以满足你的需求。

这里我实现的Button是放在EditText的右部。首先声明了一个类ButtonEditText继承自EditText,然后定义了一个Button,以及控制这个Button的高度、宽度的padding。高度的padding是指Button和EditText上下边框的距离,而宽度的padding是指Button和EditText右边框的距离。

public class ButtonEditText extends EditText {        private Button mButton;      private int mButtonHeightPadding = 10;      private int mButtonWeightPadding = 10;    }

然后根据父类定义构造函数。init()函数是定义来初始化Button的,这里初始化Button比较简单,只设置了一个Text和ClickListener,如果需要更加复杂的初始化工作,可能需要用到自定义的attribute,详见这篇文章《android中如何自定义attribute》。

public ButtonEditText(Context context) {     super(context);     init(); }  public ButtonEditText(Context context, AttributeSet attrs) {     super(context, attrs);     init(); }  public ButtonEditText(Context context, AttributeSet attrs, int defStyle) {     super(context, attrs, defStyle);     init(); }  private void init() {     mButton = new Button(getContext());     mButton.setText("ME");     mButton.setOnClickListener(new View.OnClickListener() {         @Override         public void onClick(View v) {             Toast.makeText(getContext(), "Clicked me!", Toast.LENGTH_SHORT).show();         }     }); } 

为了实现Button的点击效果,必须要把Touch的事件传递给Button,所以必须要重载dispatchTouchEvent()函数,如下:

@Override public boolean dispatchTouchEvent(MotionEvent event) {     if (event.getY() > mButtonHeightPadding && event.getY() < getHeight() - mButtonHeightPadding &&             event.getX() > getWidth() - mButtonWeightPadding - mButton.getMeasuredWidth() &&             event.getX() < getWidth() - mButtonWeightPadding) {         return mButton.dispatchTouchEvent(event);     }      return super.dispatchTouchEvent(event); } 

上面的对event.getY() 和event.getX()的判断就是为了定位Touch事件发生在Button上,如果发生在Button上,就给它传递Touch事件。否则就用EditText的dispatchTouchEvent()函数。如果你需要对Button做一些高级的效果,这里可能还需要判断Button是否需要ACTION_OUTSIDE/ACTION_CANCEL消息。

下面就需要对Button的显示进行处理了。显示首先是measure()、layout(),然后是draw(),缺一不可。重载如下:

@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {     super.onMeasure(widthMeasureSpec, heightMeasureSpec);      mButton.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),             MeasureSpec.makeMeasureSpec(getMeasuredHeight() - mButtonHeightPadding * 2, MeasureSpec.EXACTLY)); }  @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) {     super.onLayout(changed, left, top, right, bottom);      mButton.layout(0, 0, mButton.getMeasuredWidth(), mButton.getMeasuredHeight()); }  @Override protected void dispatchDraw(Canvas canvas) {     super.dispatchDraw(canvas);      canvas.save();     canvas.translate(getMeasuredWidth() - (mButton.getMeasuredWidth() + mButtonWeightPadding), mButtonHeightPadding);     mButton.draw(canvas);     canvas.restore(); } 

最后的效果如下图所示:


附完整源文件:

import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;  public class ButtonEditText extends EditText {      private Button mButton;     private int mButtonHeightPadding = 10;     private int mButtonWeightPadding = 10;      public ButtonEditText(Context context) {         super(context);         init();     }      public ButtonEditText(Context context, AttributeSet attrs) {         super(context, attrs);         init();     }      public ButtonEditText(Context context, AttributeSet attrs, int defStyle) {         super(context, attrs, defStyle);         init();     }      private void init() {         mButton = new Button(getContext());         mButton.setText("ME");         mButton.setOnClickListener(new View.OnClickListener() {             @Override             public void onClick(View v) {                 Toast.makeText(getContext(), "Clicked me!", Toast.LENGTH_SHORT).show();             }         });     }      @Override     public boolean dispatchTouchEvent(MotionEvent event) {         if (event.getY() > mButtonHeightPadding && event.getY() < getHeight() - mButtonHeightPadding &&                 event.getX() > getWidth() - mButtonWeightPadding - mButton.getMeasuredWidth() &&                 event.getX() < getWidth() - mButtonWeightPadding) {             return mButton.dispatchTouchEvent(event);         }          return super.dispatchTouchEvent(event);     }      @Override     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         super.onMeasure(widthMeasureSpec, heightMeasureSpec);          mButton.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),                 MeasureSpec.makeMeasureSpec(getMeasuredHeight() - mButtonHeightPadding * 2, MeasureSpec.EXACTLY));     }      @Override     protected void onLayout(boolean changed, int left, int top, int right, int bottom) {         super.onLayout(changed, left, top, right, bottom);          mButton.layout(0, 0, mButton.getMeasuredWidth(), mButton.getMeasuredHeight());     }      @Override     protected void dispatchDraw(Canvas canvas) {         super.dispatchDraw(canvas);          canvas.save();         canvas.translate(getMeasuredWidth() - (mButton.getMeasuredWidth() + mButtonWeightPadding), mButtonHeightPadding);         mButton.draw(canvas);         canvas.restore();     } } 
原创粉丝点击