自定义EditText :下划线,左侧有可变图标,右侧有可变删除标志
来源:互联网 发布:有哪些软件源 编辑:程序博客网 时间:2024/05/02 02:33
项目要求:1做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的edittext,如图
记录制作过程:
第一版本:
public 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() {@Overridepublic void onTextChanged(CharSequence arg0, int arg1, int arg2,int arg3) {}@Overridepublic void beforeTextChanged(CharSequence arg0, int arg1,int arg2, int arg3) {}@Overridepublic void afterTextChanged(Editable arg0) {setDrawable();}});setDrawable();}@Overrideprotected 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);}}// 处理删除事件@Overridepublic 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);}@Overrideprotected void onFocusChanged(boolean focused, int direction,Rect previouslyFocusedRect) {super.onFocusChanged(focused, direction, previouslyFocusedRect);if (focused) {setStatus(STATUS_FOCUSED);} else {setStatus(STATUS_UNFOCUSED);}}@Overrideprotected 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 当手机点击时,第一个先走的函数,当点击右侧删除图标是清空edittext
setStatus 更具不同的状态,左边的图片不一样
存在的问题:
这版本虽然基本功能已经实现,但是不符合需求,设计中要求文本框中无文字时,右侧删除按钮不显示,不点击删除按钮,删除按钮要保持灰色,点击时才可以变蓝色。因此有了第二个版本
public 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);}@Overrideprotected 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);//}//}// 处理删除事件@Overridepublic 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(); } } @Overrideprotected 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);}}@Overrideprotected void finalize() throws Throwable {super.finalize();};public void setColor(int color) {this.color = color;this.setTextColor(color);invalidate();}@Overridepublic void afterTextChanged(Editable arg0) {// TODO Auto-generated method stubpostInvalidate();}@Overridepublic 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); } } }@Overridepublic void onFocusChange(View arg0, boolean arg1) {// TODO Auto-generated method stubtry { this.hasFocus = arg1; } catch (Exception e) { e.printStackTrace(); } } }
效果图:
比较关键的方法是:onTouchEvent
当进入界面,点击输入框,要判断输入框中是否已有文字,如果有则显示灰色的删除按钮,如果没有则不显示,如果点击了删除按钮,删除按钮变蓝色
存在的问题:
这个版本依旧存在问题,就是输入长度超过输入框,所画的线不会延伸,如图
@Overrideprotected 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_32466
http://www.oschina.net/android/125/attrs-xml
http://blog.csdn.net/llew2011/article/details/28909193
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2013/0307/986.html
0 0
- 自定义EditText :下划线,左侧有可变图标,右侧有可变删除标志
- 自定义EditText :下划线,左侧有可变图标,右侧有可变删除标志
- 使用Toolbar/ActionBar自定义布局时,左侧/右侧有一段无法使用
- 菜鸟问题:EditText有下划线显示,去除下划线
- 自定义UISearchBar背景、边框、左侧图标、删除图标、取消按钮
- Android 自定义EditText 实现获得焦点并且有内容显示右侧图片并点击清空内容
- 自定义带删除图标的EditText
- EditText 自定义下划线颜色
- EditText自定义下划线
- EditText自定义下划线
- PHP中可变变量和php可变函数到底有什么用?
- 怎样写一个有可变参数的函数?
- PHP中可变变量到底有什么用?
- SVLC & UVLC 有/无符号可变长编码
- 怎样写一个有可变参数的函数?
- JAVA的可变参数,参数中有三个点
- JAVA的可变参数,参数中有三个点
- AVA的可变参数,参数中有三个点
- Julia语言:让高性能科学计算人人可用(转)
- 【JavaScript】如何编写可维护的JavaScript代码?
- hdu1021 Fibonacci Again
- 东大OJ 2SAT 异或
- VMWare vSphere - CPU性能分析与监控之就绪时间(ready time)分析
- 自定义EditText :下划线,左侧有可变图标,右侧有可变删除标志
- Shortest Prefixes(字典树)
- 内核学习总结(一)
- Android的基本控件(上,章节摘要)
- 【规范】C语言中定义变量只能在一个函数或一个块的开始吗?
- Agri-Net(最小生成树_prim||kruskral )
- EJB3.0变通实现定时任务quartz,schedule ,task,EJB3.0注入Quartz无法注入,注入失败,NullpiontException
- POJ 2031-Building a Space Station(最小生成树)
- sed 命令