How does Android customize the EditText underline? _android

Source: Internet
Author: User
Tags gettext stub throwable

Once did a project where the interactive login interface was impressive. The interaction designer gives a very designed design that includes an underscore that can be discolored according to the situation, a variable icon on the left, and an input box with a variable deletion mark on the right, as shown

Record production process:

First version

public class Lineedittext extends EditText {private Paint mpaint; private int color; public static final int STATUS_FOC
USED = 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;//default private int unfocuseddrawableid = R.drawable.user;
private int errordrawableid = R.drawable.user_error;
Drawable left = null;
Private context Mcontext;
 Public Lineedittext {Super (context);
 Mcontext = context;
Init ();
 Public Lineedittext (context, AttributeSet attrs) {Super (context, attrs);
 Mcontext = context;

Init ();
 Public Lineedittext (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); //delete picture private void setdrawable () {if (length () < 1) {setcompounddrawableswithintrinsicbounds (left, NULL, DEL_
 BTN, NULL);
 else {setcompounddrawableswithintrinsicbounds (left, NULL, del_btn_down,null); }//Handle deletion event @Override public boolean ontouchevent (Motionevent event) {if del_btn_down!= null && EVENT.GETAC
  tion () = = 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.focuseddrawa
 Bleid = Focuseddrawableid;
 This.unfocuseddrawableid = Unfocuseddrawableid;
 This.errordrawableid = Errordrawableid; SetStatus (StATUS); @Override protected void Onfocuschanged (Boolean focused, int direction, Rect previouslyfocusedrect) {SUPER.ONFOCUSC
 Hanged (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 ();

 }
}

Effect Chart:


Code Explanation:

The variable name status_focused,status_unfocused,status_error three states, the selected status is blue, the unchecked state is gray, and the error status is red. Focuseddrawableid Unfocuseddrawableid Errordrawableid holds three states of the picture, placed on the left.

Canvas.drawline (0, This.getheight ()-1, This.getwidth (), This.getheight ()-1, mpaint); Draw EditText at the bottom of the line setcompounddrawableswithintrinsicbounds (left, NULL, DEL_BTN, NULL); Place the left and right pictures (left, top, right, bottom) equivalent to android:drawableleft= "" android:drawableright= ""

1, ontouchevent when the mobile phone clicks, the first executive function, when the click on the right to delete the icon is empty EditText
2, SetStatus according to the different state, the picture on the left is not the same

The problem: This version although the basic function has been implemented, but does not meet the requirements, the design requirements in the text box without text, the right to delete the button does not display, do not click the Delete button, delete the button to keep the gray, click can be changed to blue.

So there's a second version.

public class Lineedittext extends EditText implements Textwatcher, <br/> onfocuschangelistener{private Paint mPa
int
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;//default private int unfocuseddrawableid = R.drawable.user;
private int errordrawableid = R.drawable.user_error;
Drawable left = null;
Private context Mcontext; 
/** * Whether to get focus, default no focus * * Private Boolean hasfocus = false; 

/** * When the finger is raised, the x-coordinate/private int xup = 0;
 Public Lineedittext {Super (context);
 Mcontext = context;
Init ();
 Public Lineedittext (context, AttributeSet attrs) {Super (context, attrs);
 Mcontext = context;

Init ();
 Public Lineedittext (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); //delete picture//private void setdrawable () {//if (length () < 1) {//Setcompounddrawableswithintrinsicbounds (left, NULL , NULL, NULL); else {//setcompounddrawableswithintrinsicbounds (left, NULL, del_btn,null);//}////Process Delete event @Override public bo  Olean Ontouchevent (Motionevent event) {if (del_btn!= null && event.getaction () = = motionevent.action_up) {// 
  Get the X coordinate xup = (int) event.getx () when the finger is raised when clicked; 
  LOG.E ("Xup", xup+ "");
  /*rect Rect = new Rect ();
  Getglobalvisiblerect (rect);  Rect.left = rect.right-50;*////when the distance between the clicked coordinates to the right of the current input box is less than the distance equal to Getcompoundpaddingright (), it is considered to have clicked the Delete icon 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, +);//This.setcompounddrawables (left, NULL, NULL, NULL); setcompoundd Rawableswithintrinsicbounds (Left,null,null,NULL); } postinvalidate (); public void setleftdrawable (int focuseddrawableid, int unfocuseddrawableid, int errordrawableid) {This.focuseddrawa
 Bleid = 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.onfo
 Cuschanged (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 ();
} @Overridepublic 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 Metho  D Stub if (Textutils.isempty (arg0)) {//If empty, the delete icon setcompounddrawableswithintrinsicbounds (left, NULL, NULL, 
  NULL); 
  else {//if non-null, display the delete icon Setcompounddrawableswithintrinsicbounds (left, NULL, DEL_BTN, NULL); @Override public void ontextchanged (charsequence s, int start, int before, int after) {if (Hasfocus) {if (Tex 
  Tutils.isempty (s)) {//If empty, the delete icon is not displayed setcompounddrawableswithintrinsicbounds (left, NULL, NULL, NULL); 
  else {//if non-null, display the delete icon Setcompounddrawableswithintrinsicbounds (left, NULL, DEL_BTN, NULL); @Override public void Onfocuschange (View arg0, Boolean arg1) {//TODO auto-generated method stub try {thi 
 S.hasfocus = arg1; 
 catch (Exception e) {e.printstacktrace (); }
} 
}

 

The more critical approach is:ontouchevent

When entering the interface, click on the input box, to determine whether there is text in the input box, if there is a gray delete button, if it does not show, if you clicked the Delete button, the Delete button to become blue

The problem: This version still has a problem, that is, the input length exceeds the input box, the drawn line does not extend, as shown


Workaround:

@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: Get Control length

X: Length after extension

Final effect:

This is the Android implementation of a custom EditText underline method, I hope to help you learn.

Related Article

E-Commerce Solutions

Leverage the same tools powering the Alibaba Ecosystem

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.