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.