有很多人希望能在一个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,详见这篇文章http://sxote.blog.51cto.com/885634/1112857。

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

更多相关文章

  1. Android 自定义View 解耦框架
  2. Android 自定义组件02
  3. android中颜色的定义
  4. Android一些实用的函数
  5. 将retrofit2和rxjava的初始化配置到application
  6. Android调用系统自定义设置界面
  7. Android 自定义布局的Toast
  8. Android 之 自定义适配器
  9. Android 自定义view的简单应用(2) 毛玻璃效果

随机推荐

  1. 学习android的好博客
  2. Android新建项目后src下没有自动生成文件
  3. 跟Google学习Android开发-起始篇-保存数
  4. 【Android游戏开发二十二】(图文详解)游戏
  5. 《今日求职》之拉勾网Android客户端产品
  6. Android(安卓)编译文件使其支持wml
  7. android消息处理机制原理解析
  8. Android(安卓)studio Error:(30, 31) 错
  9. [置顶] Android(安卓)轻松实现后台搭建+A
  10. 利用SharedPreferences(持久化技术)实现