自定义EditText :下划线,左侧有可变图标,右侧有可变删除标志

来源:互联网 发布:c语言 flag语句 编辑:程序博客网 时间:2024/05/02 00:13
项目要求:1做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的edittext,如图记录制作过程:第一版本:[java] view plain copypublic class LineEditText extends EditText {      private Paint mPaint;      private int color;      public static final int STATUS_FOCUSED = 1;      public static final int STATUS_UNFOCUSED = 2;      public static final int STATUS_ERROR = 3;      private int status = 2;      private Drawable del_btn;      private Drawable del_btn_down;      private int focusedDrawableId = R.drawable.user_select;// 默认的      private int unfocusedDrawableId = R.drawable.user;      private int errorDrawableId = R.drawable.user_error;      Drawable left = null;      private Context mContext;        public LineEditText(Context context) {          super(context);          mContext = context;          init();      }        public LineEditText(Context context, AttributeSet attrs) {          super(context, attrs);          mContext = context;          init();        }        public LineEditText(Context context, AttributeSet attrs, int defStryle) {          super(context, attrs, defStryle);          mContext = context;          TypedArray a = context.obtainStyledAttributes(attrs,                  R.styleable.lineEdittext, defStryle, 0);          focusedDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableFocus, R.drawable.user_select);          unfocusedDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableUnFocus, R.drawable.user);          errorDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableError, R.drawable.user_error);          a.recycle();          init();      }        /**      * 2014/7/31      *       * @author Aimee.ZHANG      */      private void init() {          mPaint = new Paint();          // mPaint.setStyle(Paint.Style.FILL);          mPaint.setStrokeWidth(3.0f);          color = Color.parseColor("#bfbfbf");          setStatus(status);          del_btn = mContext.getResources().getDrawable(R.drawable.del_but_bg);          del_btn_down = mContext.getResources().getDrawable(R.drawable.del_but_bg_down);          addTextChangedListener(new TextWatcher() {                @Override              public void onTextChanged(CharSequence arg0, int arg1, int arg2,                      int arg3) {              }                @Override              public void beforeTextChanged(CharSequence arg0, int arg1,                      int arg2, int arg3) {              }                @Override              public void afterTextChanged(Editable arg0) {                  setDrawable();              }          });          setDrawable();      }        @Override      protected void onDraw(Canvas canvas) {          super.onDraw(canvas);          mPaint.setColor(color);          canvas.drawLine(0, this.getHeight() - 1, this.getWidth(),                  this.getHeight() - 1, mPaint);      }        // 删除图片      private void setDrawable() {          if (length() < 1) {              setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn, null);          } else {              setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn_down,null);          }      }        // 处理删除事件      @Override      public boolean onTouchEvent(MotionEvent event) {          if (del_btn_down != null && event.getAction() == MotionEvent.ACTION_UP) {              int eventX = (int) event.getRawX();              int eventY = (int) event.getRawY();              Log.e("eventXY", "eventX = " + eventX + "; eventY = " + eventY);                Rect rect = new Rect();              getGlobalVisibleRect(rect);              rect.left = rect.right - 50;              if (rect.contains(eventX, eventY))              setText("");          }          return super.onTouchEvent(event);      }        public void setStatus(int status) {          this.status = status;                      if (status == STATUS_ERROR) {              try {                  left = getResources().getDrawable(errorDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#f57272"));          } else if (status == STATUS_FOCUSED) {              try {                  left = getResources().getDrawable(focusedDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#5e99f3"));          } else {              try {                  left = getResources().getDrawable(unfocusedDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#bfbfbf"));          }          if (left != null) {  //          left.setBounds(0, 0, 30, 40);  //          this.setCompoundDrawables(left, null, null, null);              setCompoundDrawablesWithIntrinsicBounds(left,null,del_btn,null);          }          postInvalidate();      }        public void setLeftDrawable(int focusedDrawableId, int unfocusedDrawableId,              int errorDrawableId) {          this.focusedDrawableId = focusedDrawableId;          this.unfocusedDrawableId = unfocusedDrawableId;          this.errorDrawableId = errorDrawableId;          setStatus(status);      }        @Override      protected void onFocusChanged(boolean focused, int direction,              Rect previouslyFocusedRect) {          super.onFocusChanged(focused, direction, previouslyFocusedRect);          if (focused) {              setStatus(STATUS_FOCUSED);          } else {              setStatus(STATUS_UNFOCUSED);          }      }        @Override      protected void finalize() throws Throwable {          super.finalize();      };        public void setColor(int color) {          this.color = color;          this.setTextColor(color);          invalidate();      }  }  效果图:代码解释: 变量名 STATUS_FOCUSED,STATUS_UNFOCUSED,STATUS_ERROR 标示了三种状态,选中状况为蓝色,未选中状态为灰色,错误状态为红色。focusedDrawableId   unfocusedDrawableId  errorDrawableId 存放三种状态的图片,放置于最左侧。canvas.drawLine(0, this.getHeight() - 1, this.getWidth(),this.getHeight() - 1, mPaint);     //画editText最下方的线setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn, null);  //放置左边的和右边的图片(左,上,右,下)相当于 android:drawableLeft=""  android:drawableRight=""  onTouchEvent  当手机点击时,第一个先走的函数,当点击右侧删除图标是清空edittextsetStatus  更具不同的状态,左边的图片不一样存在的问题:这版本虽然基本功能已经实现,但是不符合需求,设计中要求文本框中无文字时,右侧删除按钮不显示,不点击删除按钮,删除按钮要保持灰色,点击时才可以变蓝色。因此有了第二个版本[java] view plain copypublic class LineEditText extends EditText  implements TextWatcher,    OnFocusChangeListener{      private Paint mPaint;      private int color;      public static final int STATUS_FOCUSED = 1;      public static final int STATUS_UNFOCUSED = 2;      public static final int STATUS_ERROR = 3;      private int status = 2;      private Drawable del_btn;      private Drawable del_btn_down;      private int focusedDrawableId = R.drawable.user_select;// 默认的      private int unfocusedDrawableId = R.drawable.user;      private int errorDrawableId = R.drawable.user_error;      Drawable left = null;      private Context mContext;      /**       * 是否获取焦点,默认没有焦点       */        private boolean hasFocus = false;        /**       * 手指抬起时的X坐标       */        private int xUp = 0;          public LineEditText(Context context) {          super(context);          mContext = context;          init();      }        public LineEditText(Context context, AttributeSet attrs) {          super(context, attrs);          mContext = context;          init();        }        public LineEditText(Context context, AttributeSet attrs, int defStryle) {          super(context, attrs, defStryle);          mContext = context;          TypedArray a = context.obtainStyledAttributes(attrs,                  R.styleable.lineEdittext, defStryle, 0);          focusedDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableFocus, R.drawable.user_select);          unfocusedDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableUnFocus, R.drawable.user);          errorDrawableId = a.getResourceId(                  R.styleable.lineEdittext_drawableError, R.drawable.user_error);          a.recycle();          init();      }        /**      * 2014/7/31      *       * @author Aimee.ZHANG      */      private void init() {          mPaint = new Paint();          // mPaint.setStyle(Paint.Style.FILL);          mPaint.setStrokeWidth(3.0f);          color = Color.parseColor("#bfbfbf");          setStatus(status);          del_btn = mContext.getResources().getDrawable(R.drawable.del_but_bg);          del_btn_down = mContext.getResources().getDrawable(R.drawable.del_but_bg_down);          addListeners();          setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);      }        @Override      protected void onDraw(Canvas canvas) {          super.onDraw(canvas);          mPaint.setColor(color);          canvas.drawLine(0, this.getHeight() - 1, this.getWidth(),                  this.getHeight() - 1, mPaint);      }        // 删除图片  //  private void setDrawable() {  //      if (length() < 1) {  //          setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);  //      } else {  //          setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn,null);  //      }  //  }        // 处理删除事件      @Override      public boolean onTouchEvent(MotionEvent event) {          if (del_btn != null && event.getAction() == MotionEvent.ACTION_UP) {              // 获取点击时手指抬起的X坐标                xUp = (int) event.getX();                Log.e("xUp", xUp+"");                /*Rect rect = new Rect();             getGlobalVisibleRect(rect);             rect.left = rect.right - 50;*/                // 当点击的坐标到当前输入框右侧的距离小于等于getCompoundPaddingRight()的距离时,则认为是点击了删除图标                if ((getWidth() - xUp) <= getCompoundPaddingRight()) {                    if (!TextUtils.isEmpty(getText().toString())) {                      setText("");                    }                }          }else if(del_btn != null && event.getAction() == MotionEvent.ACTION_DOWN && getText().length()!=0){              setCompoundDrawablesWithIntrinsicBounds(left,null,del_btn_down,null);          }else if(getText().length()!=0){              setCompoundDrawablesWithIntrinsicBounds(left,null,del_btn,null);          }          return super.onTouchEvent(event);      }        public void setStatus(int status) {          this.status = status;                      if (status == STATUS_ERROR) {              try {                  left = getResources().getDrawable(errorDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#f57272"));          } else if (status == STATUS_FOCUSED) {              try {                  left = getResources().getDrawable(focusedDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#5e99f3"));          } else {              try {                  left = getResources().getDrawable(unfocusedDrawableId);              } catch (NotFoundException e) {                  e.printStackTrace();              }              setColor(Color.parseColor("#bfbfbf"));          }          if (left != null) {  //          left.setBounds(0, 0, 30, 40);  //          this.setCompoundDrawables(left, null, null, null);              setCompoundDrawablesWithIntrinsicBounds(left,null,null,null);          }          postInvalidate();      }        public void setLeftDrawable(int focusedDrawableId, int unfocusedDrawableId,              int errorDrawableId) {          this.focusedDrawableId = focusedDrawableId;          this.unfocusedDrawableId = unfocusedDrawableId;          this.errorDrawableId = errorDrawableId;          setStatus(status);      }       private void addListeners() {                try {                    setOnFocusChangeListener(this);                    addTextChangedListener(this);                } catch (Exception e) {                    e.printStackTrace();                }            }        @Override      protected void onFocusChanged(boolean focused, int direction,              Rect previouslyFocusedRect) {          super.onFocusChanged(focused, direction, previouslyFocusedRect);          this.hasFocus=focused;          if (focused) {              setStatus(STATUS_FOCUSED);          } else {              setStatus(STATUS_UNFOCUSED);              setCompoundDrawablesWithIntrinsicBounds(left,null,null,null);          }      }        @Override      protected void finalize() throws Throwable {          super.finalize();      };        public void setColor(int color) {          this.color = color;          this.setTextColor(color);          invalidate();      }                @Override      public void afterTextChanged(Editable arg0) {          // TODO Auto-generated method stub          postInvalidate();      }        @Override      public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,              int arg3) {          // TODO Auto-generated method stub           if (TextUtils.isEmpty(arg0)) {                 // 如果为空,则不显示删除图标                 setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);             } else {                 // 如果非空,则要显示删除图标                 setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn, null);             }        }      @Override       public void onTextChanged(CharSequence s, int start, int before, int after) {           if (hasFocus) {               if (TextUtils.isEmpty(s)) {                   // 如果为空,则不显示删除图标                   setCompoundDrawablesWithIntrinsicBounds(left, null, null, null);               } else {                   // 如果非空,则要显示删除图标                   setCompoundDrawablesWithIntrinsicBounds(left, null, del_btn, null);               }           }       }        @Override      public void onFocusChange(View arg0, boolean arg1) {          // TODO Auto-generated method stub          try {                this.hasFocus = arg1;            } catch (Exception e) {                e.printStackTrace();            }        }    }  效果图:比较关键的方法是:onTouchEvent当进入界面,点击输入框,要判断输入框中是否已有文字,如果有则显示灰色的删除按钮,如果没有则不显示,如果点击了删除按钮,删除按钮变蓝色存在的问题:这个版本依旧存在问题,就是输入长度超过输入框,所画的线不会延伸,如图解决办法:[java] view plain copy@Override      protected void onDraw(Canvas canvas) {          super.onDraw(canvas);          mPaint.setColor(color);          int x=this.getScrollX();          int w=this.getMeasuredWidth();          canvas.drawLine(0, this.getHeight() - 1, w+x,                  this.getHeight() - 1, mPaint);      }  w:获取控件长度X:延伸后的长度最终效果:参考文献:http://www.oschina.net/question/54100_32466http://www.oschina.net/android/125/attrs-xmlhttp://blog.csdn.net/llew2011/article/details/28909193http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0307/986.html
http://blog.csdn.net/zwx622/article/details/38340991#comments 原文链接

0 0
原创粉丝点击