Android 邮箱自动补全-MultiAutoCompleteTextView实现

阅读:1142 2019-03-20 14:08:10 来源:新网

因为项目需要,要写一个邮箱自动补全的edittext,刚开始考虑使用autocompletetextview来实现,但是满足不到需求官方组件太low了。。。

先来介绍下autocompletetextview的使用:activity

importandroid.os.bundle;importandroid.support.v7.app.appcompatactivity;importandroid.widget.arrayadapter;importandroid.widget.autocompletetextview;publicclassmainactivityextendsappcompatactivity{privatestaticfinalstring[]countries=newstring[]{"belgium","france","italy","germany","spain"};privateautocompletetextviewmautocompletetextview;@overrideprotectedvoidoncreate(bundlesavedinstancestate){super.oncreate(savedinstancestate);setcontentview(r.layout.activity_main);mautocompletetextview=(autocompletetextview)findviewbyid(r.id.autocompletetextview);arrayadapteradapter=newarrayadapter(this,android.r.layout.simple_dropdown_item_1line,countries);mautocompletetextview.setadapter(adapter);}}

xml

使用方法很简单,获取到组件然后设置一个弹出的adapter就能完成一个自动提示。

但是这个组件有几个特性不是很满足我们的需求。1.默认是第二个字母开始匹配2.整体内容匹配模式belgium我们只能输入b,be,bel等才会匹配注:邮箱格式为123456@xx.com,整体内容肯定不行。

下面我们又看到一个multiautocompletetextview组件,来看下multiautocompletetextview能否满足我们的需求

importandroid.os.bundle;importandroid.support.v7.app.appcompatactivity;importandroid.widget.arrayadapter;importandroid.widget.autocompletetextview;importandroid.widget.multiautocompletetextview;publicclassmainactivityextendsappcompatactivity{privatestaticfinalstring[]countries=newstring[]{"belgium","france","italy","germany","spain"};privateautocompletetextviewmautocompletetextview;privatemultiautocompletetextviewmmultiautocompletetextview;@overrideprotectedvoidoncreate(bundlesavedinstancestate){super.oncreate(savedinstancestate);setcontentview(r.layout.activity_main);mautocompletetextview=(autocompletetextview)findviewbyid(r.id.autocompletetextview);mmultiautocompletetextview=(multiautocompletetextview)findviewbyid(r.id.multiautocompletetextview);arrayadapteradapter=newarrayadapter(this,android.r.layout.simple_dropdown_item_1line,countries);mautocompletetextview.setadapter(adapter);mmultiautocompletetextview.setadapter(adapter);mmultiautocompletetextview.settokenizer(newmultiautocompletetextview.commatokenizer());}}

xml

activity经过查询api我们知道multiautocompletetextview继承于autocompletetextview继承于edittextapi中在multiautocompletetextview提供了一个接口multiautocompletetextview.tokenizer可以用来匹配提示的子字符串。好吧,勉强能实现需求。首先看multiautocompletetextview源码中有一个对tokenizer接口的实现!然后换成我们的。

/***thissimpletokenizercanbeusedforlistswheretheitemsare*separatedbyacommaandoneormorespaces.*/publicstaticclasscommatokenizerimplementstokenizer{publicintfindtokenstart(charsequencetext,intcursor){inti=cursor;while(i>0&&text.charat(i-1)!=','){i--;}while(i0&&text.charat(i-1)==''){i--;}if(i>0&&text.charat(i-1)==','){returntext;}else{if(textinstanceofspanned){spannablestringsp=newspannablestring(text+",");textutils.copyspansfrom((spanned)text,0,text.length(),object.class,sp,0);returnsp;}else{returntext+",";}}}}

根据multiautocompletetextview源码中的实现,我们知道tokenizer的实现方式。

importandroid.text.spannablestring;importandroid.text.spanned;importandroid.text.textutils;importandroid.widget.multiautocompletetextview;publicclassemailautotokenizerimplementsmultiautocompletetextview.tokenizer{@overridepublicintfindtokenend(charsequencetext,intcursor){inti=cursor;intlen=text.length();while(i=findtokenend(text,cursor)){index=0;}returnindex;}@overridepubliccharsequenceterminatetoken(charsequencetext){inti=text.length();while(i>0&&text.charat(i-1)==''){i--;}if(i>0&&text.charat(i-1)=='@'){returntext;}else{if(textinstanceofspanned){spannablestringsp=newspannablestring(text);textutils.copyspansfrom((spanned)text,0,text.length(),object.class,sp,0);returnsp;}else{returntext;}}}}

在activity中把tokenizer换成我们自己的看下效果mmultiautocompletetextview.settokenizer(newemailautotokenizer());

importandroid.os.bundle;importandroid.support.v7.app.appcompatactivity;importandroid.widget.arrayadapter;importandroid.widget.autocompletetextview;importandroid.widget.multiautocompletetextview;publicclassmainactivityextendsappcompatactivity{privatestring[]email_sufixs=newstring[]{"@qq.com","@163.com","@126.com","@gmail.com","@sina.com","@hotmail.com","@yahoo.cn","@sohu.com","@foxmail.com","@139.com","@yeah.net","@vip.qq.com","@vip.sina.com"};privateautocompletetextviewmautocompletetextview;privatemultiautocompletetextviewmmultiautocompletetextview;@overrideprotectedvoidoncreate(bundlesavedinstancestate){super.oncreate(savedinstancestate);setcontentview(r.layout.activity_main);mautocompletetextview=(autocompletetextview)findviewbyid(r.id.autocompletetextview);mmultiautocompletetextview=(multiautocompletetextview)findviewbyid(r.id.multiautocompletetextview);arrayadapteradapter=newarrayadapter(this,android.r.layout.simple_dropdown_item_1line,email_sufixs);mautocompletetextview.setadapter(adapter);mmultiautocompletetextview.setadapter(adapter);mmultiautocompletetextview.settokenizer(newemailautotokenizer());}}

看下最后的效果图,当然我们还需要对弹出框进行调整下,自己去查询api吧!提供有方法。

正当我高兴的时候,万恶的产品dog给我加一个右边删除效果,丢一个验证规则过来!

在@之后输入字母,从输入的字母开始suggest邮箱点击suggest的邮箱,邮箱被输入到邮箱输入栏里,光标移动到下一textbox例:1.输入:monoqn→不suggest1.输入:monoqn@→不suggest1.输入:monoqn@i→monoqn@i.softbank.jp/monoqn@icloud.com1.输入:monoqn@ic→monoqn@icloud.com

下面先验证规则:1.在@之后输入字母,从输入的字母开始suggest邮箱。很简单android:completionthreshold=”2”设置输入几个字符之后显示下拉菜单,默认为2个。不用管就行2.点击suggest的邮箱,邮箱被输入到邮箱输入栏里,光标移动到下一textbox也简单multiautocompletetextview中有onitemclicklistener事件,

email.setonitemclicklistener((parent,view1,position,id)->password.requestfocus());

3.显示规则看下了满足需求,666666!

最后一个右边加入删除按钮!本宝宝自定义一个就ok。

importandroid.content.context;importandroid.graphics.drawable.drawable;importandroid.text.editable;importandroid.text.textutils;importandroid.text.textwatcher;importandroid.util.attributeset;importandroid.view.motionevent;importandroid.view.view;importandroid.widget.multiautocompletetextview;publicclasscleanablemultiautocompletetextviewextendsmultiautocompletetextview{privatedrawablemrightdrawable;publiccleanablemultiautocompletetextview(contextcontext){super(context);init();}publiccleanablemultiautocompletetextview(contextcontext,attributesetattrs){super(context,attrs);init();}publiccleanablemultiautocompletetextview(contextcontext,attributesetattrs,intdefstyle){super(context,attrs,defstyle);init();}privatevoidinit(){//getcompounddrawables://returnsdrawablesfortheleft,top,right,andbottomborders.drawable[]drawables=this.getcompounddrawables();//getrightdrawableinlayout.xmlthatisandroid:drawablerightmrightdrawable=drawables[2];setonfocuschangelistener(newfocuschangelistenerimpl());addtextchangedlistener(newtextwatcherimpl());setcleardrawablevisible(false);}@overridepublicbooleanontouchevent(motioneventevent){switch(event.getaction()){casemotionevent.action_up:booleanisclean=(event.getx()>(getwidth()-gettotalpaddingright()))&&(event.getx()<(getwidth()-getpaddingright()));if(isclean){settext("");}break;}returnsuper.ontouchevent(event);}privateclassfocuschangelistenerimplimplementsonfocuschangelistener{@overridepublicvoidonfocuschange(viewv,booleanhasfocus){if(hasfocus){booleanisvisible=!textutils.isempty(gettext());setcleardrawablevisible(isvisible);}else{setcleardrawablevisible(false);}}}privateclasstextwatcherimplimplementstextwatcher{@overridepublicvoidaftertextchanged(editables){booleanisvisible=!textutils.isempty(gettext());setcleardrawablevisible(isvisible);}@overridepublicvoidbeforetextchanged(charsequences,intstart,intcount,intafter){//no-op}@overridepublicvoidontextchanged(charsequences,intstart,intbefore,intcount){//no-op}}publicvoidsetcleardrawablevisible(booleanisvisible){drawablerightdrawable=isvisible?mrightdrawable:null;setcompounddrawables(getcompounddrawables()[0],getcompounddrawables()[1],rightdrawable,getcompounddrawables()[3]);}}

相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服