返回顶部
首页 > 资讯 > 移动开发 >Android如何自定义EditText下划线?
  • 697
分享到

Android如何自定义EditText下划线?

edittextAndroid 2022-06-06 09:06:54 697人浏览 安东尼
摘要

曾经做过一个项目,其中登录界面的交互令人印象深刻。交互设计师给出了一个非常作的设计,要求做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的输入框,如图

曾经做过一个项目,其中登录界面的交互令人印象深刻。交互设计师给出了一个非常作的设计,要求做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的输入框,如图

记录制作过程:

第一版本


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

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=""

1、onTouchEvent 当手机点击时,第一个先执行的函数,当点击右侧删除图标是清空 edittext
2、setStatus 根据不同的状态,左边的图片不一样

存在的问题: 这版本虽然基本功能已经实现,但是不符合需求,设计中要求文本框中无文字时,右侧删除按钮不显示,不点击删除按钮,删除按钮要保持灰色,点击时才可以变蓝色。

因此有了第二个版本


public class LineEditText extends EditText implements TextWatcher, <br /> 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; 
 
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();
}

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+""); 
  
   // 当点击的坐标到当前输入框右侧的距离小于等于 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

当进入界面,点击输入框,要判断输入框中是否已有文字,如果有则显示灰色的删除按钮,如果没有则不显示,如果点击了删除按钮,删除按钮变蓝色

存在的问题: 这个版本依旧存在问题,就是输入长度超过输入框,所画的线不会延伸,如图


解决方法:


@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:延伸后的长度

最终效果:

以上就是Android实现自定义的EditText下划线的方法,希望对大家的学习有所帮助。

您可能感兴趣的文章:Android如何自定义EditText光标与下划线颜色详解Android更改EditText下划线颜色样式的方法Android中EditText如何去除边框添加下划线Android实现EditText添加下划线


--结束END--

本文标题: Android如何自定义EditText下划线?

本文链接: https://lsjlt.com/news/25933.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • Android如何自定义EditText下划线?
    曾经做过一个项目,其中登录界面的交互令人印象深刻。交互设计师给出了一个非常作的设计,要求做出包含根据情况可变色的下划线,左侧有可变图标,右侧有可变删除标志的输入框,如图 ...
    99+
    2022-06-06
    edittext Android
  • Android开发中如何自定义editText下划线
    这篇文章主要介绍“Android开发中如何自定义editText下划线”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Android开发中如何自定义editText下划线”文章能帮助大家解决问题。效果...
    99+
    2023-07-05
  • Android开发中自定义editText下划线
    看了下网上代码: 我想要的效果如下图 下划线和文字有15dp的间距   eeeeee的颜色 上代码, <"1.0" encoding="utf-8">...
    99+
    2023-03-08
    EditText设置下划线 EditText自定义下划线 Android如何自定义EditText下划线
  • Android如何自定义EditText光标与下划线颜色详解
    前言最近在写些小Demo复习基础,在用到EditText的时候突然发现之前几乎没有注意到它的光标和下划线的颜色,于是花了不少时间,看了不少博客,现在就来总结和分享一下收获,话不多说了,来一起看看详细的介绍:1、第一印象:原生的EditTex...
    99+
    2023-05-30
    android 自定义edittext 下划线颜色
  • Android完全自定义下划线的TabLayout
    一 介绍: 导航功能几乎是所有的APP都具备的基础功能之一,Android系统提供了TabLayout+ViewPager的组合来实现该功能。再...
    99+
    2022-06-06
    自定义 tablayout 下划线 Android
  • Android中EditText如何去除边框添加下划线
    废话不多说了,直接给大家贴代码了。 <span style="font-family: Arial, Helvetica, sans-serif;"><&...
    99+
    2022-06-06
    edittext 下划线 Android
  • HTML怎么自定义下划线的样式
    这篇文章主要讲解了“HTML怎么自定义下划线的样式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“HTML怎么自定义下划线的样式”吧!   text-dec...
    99+
    2024-04-02
  • Android EditText自定义样式的方法
    本文实例讲述了Android EditText自定义样式的方法。分享给大家供大家参考,具体如下: 1.去掉边框 EditText的background属性设置为@null就搞定...
    99+
    2022-06-06
    edittext 方法 Android
  • Android更改EditText下划线颜色样式的方法
    前言 相信大家都知道,当使用AppCompatEditText(Edit Text)时,默认的下划线是跟随系统的#FF4081的颜色值的,通过改变这个值可以改变所有的颜色样式 ...
    99+
    2022-06-06
    edittext 方法 Android
  • CSS虚线下划线及虚线怎么定义
    今天小编给大家分享一下CSS虚线下划线及虚线怎么定义的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解...
    99+
    2024-04-02
  • Android自定义EditText右侧带图片控件
    前言   最近项目做用户登录模块需要一个右边带图片的EditText,图片可以设置点击效果,所以就查资料做了一个自定义EditText出来,方便以后复用。 原理   下面是自定...
    99+
    2022-06-06
    edittext 图片 Android
  • Android 自定义EditText输入框带清空按钮
    Android 自定义EditText输入框带清空按钮当用户输入字符后 EditText会自动在输入框的内部右侧出现删除按钮重写EditText达到简化布局的效果效果图:继承EditTextpackage com.example.myedi...
    99+
    2023-05-31
    android edittext 清空按钮
  • Android如何自定义Dialog
    本篇内容主要讲解“Android如何自定义Dialog”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Android如何自定义Dialog”吧!接下来看代码:public class&n...
    99+
    2023-07-02
  • css如何取消下划线与显示下划线
    这篇文章主要介绍了css如何取消下划线与显示下划线,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 a标签下划线和勾销下划线样式text-d...
    99+
    2024-04-02
  • Android实现自定义带删除功能的EditText实例
    1.说明自定义带删除功能的EditText有两种方法,第一种是用组合视图的方法,即在一个view视图里面左侧放置一个EditText,右侧放置一个ImageView,但是这样增加了视图的层次,而且对输入内容的长度要做一定的处理。第二种是重新...
    99+
    2023-05-31
    android edittext roi
  • Android实现自定义曲线图
    一般来说应用中比较常见的是折线图,直方图这种比较多,今天来写一个项目中的需求曲线图,也是在之前的折线图基础上改进而来,看效果图 主要考虑曲线的实现以及阴影部分的实现 先看代码: i...
    99+
    2024-04-02
  • Android定制自己的EditText轻松改变底线颜色
    最近做 android 项目遇到这个问题,为了保持 app 风格一致,需要将原生的EditText底线颜色改成橙色。网上搜了一些解决方案,特此记录总结一下。 效果图 默认的Ed...
    99+
    2022-06-06
    edittext Android
  • springboot为异步任务规划自定义线程池如何实现
    本篇内容主要讲解“springboot为异步任务规划自定义线程池如何实现”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“springboot为异步任务规划自定义线程池如何实现”吧!一、Spring...
    99+
    2023-07-02
  • Android UI设计系列之自定义TextView属性实现带下划线的文本框(4)
    在Android开发过程中,如果Android系统自带的属性不能满足我们日常开发的需求,那么就需要我们给系统控件添加额外的属性了。假如有个需求是实现带下划线的文本显示(下划线)...
    99+
    2022-06-06
    下划线 文本框 Android
  • 详解Android如何实现自定义的动画曲线
    目录前言Curve 类定义实例解析正弦动画曲线总结前言 最近在写动画相关的篇章,经常会用到 Curve 这个动画曲线类,那这个类到底怎么实现的?如果想自己来一个自...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作