,,Android TextView的TextWatcher使用案例详解

,,Android TextView的TextWatcher使用案例详解

本文主要介绍Android TextView的TextWatcher用例的详细说明。本文通过一个简单的案例来说明对这项技术的理解和使用。以下是详细内容。有需要的朋友可以参考一下。

TextWatcher是一个文本更改监控接口,定义了三个接口,分别是textchanged前、textchanged上、text cahanged后。Textwatcher通常与TextView结合使用,以响应不同时间的文本变化。TextWatcher中的三个回调接口都使用由InputFilter过滤器过滤的文本字符作为新的字符对象。

施用方式

mtextview . addtextchangedlistener(new text watcher(){

@覆盖

public void before text changed(char sequence s,int start,int count,int after) {

}

@覆盖

public void onTextChanged(char sequence s,int start,int before,int count) {

}

@覆盖

text changed(editable){//阻止回车中的中英文空格

}

});

我们可以在beforeTextChanged、onTextChanged和afterTextChanged的回调方法中实现自己的业务逻辑。这三个参数代表TextView文本更改的三个阶段。

beforeTextChanged(CharSequence s, int start, int count, int after)方法在文本更改之前由TextView调用,并传入四个参数。CharSequence s参数表示当前TextView内部的mText成员变量,实际上就是当前显示的文本;start参数表示要改变的文本区域的起点,即所选文本区域的起点;int参数表示要改变的文本中的字符数,即所选文本区域的字符数;int after参数指示被替换文本中的字符数。特别是,当TextView删除文本时,after的值为0。此时,TextView使用一个空字符串,而不是需要更改的文本区域来删除文本。图1.1描述了beforeTextChanged的四个参数的含义。

图TextChanged之前的四个参数示例

TextView的setText方法通过调用sendBeforeTextChanged方法通知所有注册的TextWatcher回调beforeTextChanged方法。此时,传入的四个参数s是当前局部变量mText的值。如果该值为null,即之前没有为TextView设置要显示的文本,则s的值为“”;start的值为0;count的值是当前多行文字的长度;after的值是要显示的新文本的长度。代码1.1是在TextView中调用sendBeforeTextChanged的设置文本方法的源代码。

1.1 textview中的setText方法调用sendBeforeTextChanged的源代码。

if(多行文字!=null) {

old len=mtext . length();

sendBeforeTextChanged( mText,0,oldlen,text . length());

}否则{

sendBeforeTextChanged(',0,0,text . length());

}

当文本改变时,TextView调用onTextChanged(CharSequence s, int start, int before, int count)方法。此时,多行文字成员变量已修改为新文字,并传入了四个参数。CharSequence的参数指示当前TextView中的mText成员变量。此时,多行文字已被修改,但多行文字所代表的文字尚未显示在UI组件上。start参数指示已更改文本区域的起点;Int before参数表示改变前已改变文本区域的旧文本长度,即所选文本区域的文本长度;Int after参数表示修改后已更改文本区域的新文本长度。特别是TextView添加文本时,before的值为0,相当于TextView用新的文本替换了空的字符区。

调用所有注册的TextWatcher的onTextChanged方法后,TextView将回调afterTextChanged(Editable s)方法。此时,mText成员变量已经被修改为新的文本,传入了s,这个参数s实际上就是mText。通过这个界面,我们可以修改要再次显示的文本。

图1.2描述了TextView文本改变时这三种方法的调用流程。

图1.2文本视图文本改变时的调用过程

更改后的文本的参数类型是可编辑,这是一个可编辑的对象,该对像就文本视图的内部变量多行文字,此时的多行文字是可编辑的,实际上是一个SpannableStringBuilder对象。代码1.1是文本视图的设置文本方法中文本的转换逻辑。从代码中可以看出,当type==BufferType .EDITABLE || getKeyListener()!=null | | needEditableForNotification为真实的的时候,医药工厂会调用新可编辑的方法创建一个可编辑的对象SpannableStringBuilder。

代码1.1文本视图的设置文本方法中文本的转换逻辑

boolean needEditableForNotification=false;

if ( mListeners!=null mListeners.size()!=0) {

needEditableForNotification=true;

}

if (type==BufferType .EDITABLE || getKeyListener()!=null ||

needEditableForNotification) {

createEditorIfNeeded();

可编辑t=可医疗工厂。新的可编辑(文本);

text=t;

setFilters(t,m过滤器);

输入方法经理IMM=输入方法经理。peek实例();

如果(imm!=null)IMM。重启输入(这个);

} else if (type==BufferType .SPANNABLE ||运动!=null) {

text=mspannablefactory。newspannable(文本);

} else if(!(包装材料的文本实例)){

text=TextUtils .stringOrSpannedString(文本);

}

代码1.2是医疗工厂的新可编辑方法,该方法是一个工厂方法,创建一个SpannableStringBuilder对象。

代码1.2医药工厂的新可编辑方法

公共可编辑newEditable(字符序列源){

返回新的SpannableStringBuilder(来源);

}

SpannableStringBuilder实现了CharSequence,GetChars,Spannable,可编辑,可追加,图形操作的接口,内部的线是可以变化的。不过咱们修改更改后的文本中的参数s的时候,需要注意循环调用的潜在风险,因为SpannableStringBuilder会在自己内部保存文本视图的mChangeWatcher对象,代码1.3描述了设置过程。如代码所示,文本通过设置跨度方法添加了mChangeWatcher对象,以监听整个文本的变化,并且做回调。当文本的内容发生变化的时候,会通过跨度机制调用mChangeWatcher中的相应方法。

代码1.3文本视图的设置文本方法给多行文字添加mChangeWatcher的源码

span able sp=(span able)text;

//移除可能来自其他文本视图的任何变革观察者.

最终更改观察器[]观察器=sp。get spans(0,sp.length(),更改观察器.类);

最终(同Internationalorganizations)国际组织计数=观察者。长度;

for(int I=0;我数;i ) {

物种删除span(watchers[I]);

}

if(mChangeWatcher==null)mChangeWatcher=new change watcher();

sp.setSpan( mChangeWatcher,0,textLength,Spanned .SPAN_INCLUSIVE_INCLUSIVE |

(更改_观察者_优先级跨越SPAN _ PRIORITY _ SHIFT));

mChangeWatcher是一个变革观察者对象,变更观察者是文本视图的内部类,实现了TextWatcher,SpanWatcher接口偶,代码1.4描述了变革观察者实现的文本观察者的三个回调接口。这三个接口会分别调用文本视图的相应的方法,通知所有注册的文本观察者的调用相应的三个回调接口。其中,文本视图的handleTextChanged还会调用无效()和checkForResize()方法重绘用户界面界面。

代码1.4变更观察者实现的文本观察者的三个回调接口

文本更改前的公共void(字符序列缓冲区,int start,

int before,int after) {

.

文本视图这个。sendbeforetextchanged(buffer,start,before,after);

}

public void onTextChanged(char sequence buffer,int start,int before,int after) {

.

文本视图this.handleTextChanged(buffer,start,before,after);

.

}

公共void afterTextChanged(可编辑缓冲区){

.

文本视图这个。sendfatetextchanged(缓冲区);

.

}

通过spannableStringBuilder和ChangeWatcher类以及Span机制,android可以在文本发生变化时通知所有注册的TextWatcher方法调用相应的三个接口。但这会导致我们在修改TextWatcher的afterTextChanged中的参数S时,再次调用TextWatcher的三个回调接口,这样如果因为某些条件,导致afterTextChanged无法终止对S的修改,就会形成一个无限循环调用。类似于TextView的setText方法也会通知所有注册的TextWatchers在相应的时间调用三个接口作为响应。如果我们在TextWatcher的三个接口中调用TextView的setText方法,也会导致无限循环调用。图1.3描述了一个无限调用的例子。

图1.3无限调用示例

但有时候我们可能是需要根据业务需求更改显示的文本,比如过滤不必要的字符,过滤非法文字,添加必要的结尾字符等。这时候我们有时会在TextView中添加一个TextWatcher,然后在一个接口回调中根据传入的参数修改要显示的文本。这可以满足我们的业务需求,但可能会导致无限循环调用。要解决这个问题,可以拨打通过InputFilter来完成修改文本的目的。Input是一个接口,filter方法是内部定义的。这个方法的功能是修改传入的字符串。如果返回值为null,将保留原始字符串。代码1.5是这种方法的定义。

代码1.5InputFilter在内部定义了过滤器接口。

公共CharSequence过滤器(CharSequence源,int开始,int结束,

Spanned dest,int dstart,int dend);

如代码所示,filter方法需要传入六个参数,其中

source参数是一个字符串对象,它将替换选定的字符区域;

start参数指示源的开始位置;

end参数指示源的结束位置。三个参数source、start和end可以描述替换所选字符区域的新字符串。

Dest代表选定文本区域中的文本对象。当TextView的setText方法调用filter方法时,传入的dest是

EMPTY _ SPANNED,修改文本时,传入的

Dest是保存在TextView中的多行文字;

Dstart表示所选文本区域的起始位置;

Den表示选定文本区域的结束位置。

此方法的返回值用于替换source作为新的替换文本。

图1.4显示了一个过滤器的例子,它描述了过滤器的六个参数的含义。

图1.4过滤器示例

InputFilter接口中提供了两个子类AllCaps和LengthFilter。

AllCaps是一个将文本中所有小写字符转换为大写字符的过滤器。通过这个过滤器,TextView可以将输入文本中的小写字符转换成大写字符,然后显示出来;

LengthFilter是一个删除超过长度maxLength的字符的过滤器。在xml中配置maxLength后,TextView在创建实例时会生成一个LengthFilter的过滤器,从而实现限制显示字符长度的功能。

咱们自己也可以定义满足咱们业务需求的inputfilter,以达到在TextWatcher接口回调之前过滤掉无用或者非法字符的功能,Code 1.6是InputFilter的实现子类,过滤掉无用的空格。

代码1.6过滤掉无用的空白

静态类NoUsageCharInputFilter实现InputFilter {

@覆盖

public char sequence filter(char sequence source,int start,int end,Spanned dest,int dstart,int dend) {

返回source==null?null : source.toString()。replaceAll( ' \\ s ',' ');

}

}

在定义了InputFilter的实现子类后,我们可以将实现的过滤器添加到TextView的过滤器数组中。代码1.7是添加过滤器的一个例子。如代码所示,可以通过source.setFilters(inputFilters)方法为TextView设置InputFilter数组。因为我们的功能是添加过滤器,所以需要将source原本的过滤器数组中的元素添加到新的过滤器数组中,否则source原本的过滤器数组会被覆盖掉,即使我们在xml文件中配置maxLength,source也不会使用LengthInputFilter来限制文本的长度。

1.7添加过滤器的示例

公共静态void addNoUsageCharInputFilter(TextView源){

if (source==null)

返回;

input filter[]input filters=new input filter[source . get filters()!=null?source.getFilters()。长度1:1];

input filters[0]=new NoUsageCharInputFilter();

if (source.getFilters()!=null) {

for(int I=0;i source.getFilters()。长度;我)

input filters[I 1]=source . get filters()[I];

}

source.setFilters(输入过滤器);

}

在TEX设置过滤器数组之后,它的setText方法将在调用sendBeforeTextChanged之前用过滤器数组中的过滤器修改传入的文本参数。setText方法调用过滤器的实现见代码1.8。

代码1.8 texview中setText调用过滤器的实现代码

int n=mFilters.length

for(int I=0;I n;i ) {

CharSequence out=mFilters[i]。filter(text,0,text.length(),EMPTY _ SPANNED,0,0);

如果(出!=null) {

text=out

}

}

if (notifyBefore) {

if(多行文字!=null) {

old len=mtext . length();

sendBeforeTextChanged(mText,0,oldlen,text . length());

}否则{

sendBeforeTextChanged(',0,0,text . length());

}

}

通过以上分析:

1.我们可以使用TextWatcher来监控TextView文本变化的三个机会,并在回调函数中做相应的处理;

2.但是在回调函数中处理业务时,需要注意不要调用TextView的setText方法,否则会出现无限循环调用;

3.在修改TextWatcher的回调接口afterTextChanged方法中的参数S时,还需要注意的是,修改S后会触发文本的改变,导致TextView中所有注册的text watcher再次回调它们的三个回调函数。这时候就要防止无限循环调用的发生。

4.如果需要修改传入文本,可以实现InputFilter接口,然后在TextView中添加符合业务需求的过滤器;

5.向TextView添加自定义滤镜时,需要注意的是,使用setFilter方法设置滤镜将会覆盖TextView的原始滤镜。如果不想丢弃TextView原来的滤镜,需要将原来的滤镜添加到新的滤镜数组中。

6.当TextView使用InputFilter数组时,从第一个滤镜到最后一个滤镜依次使用,所以我们在为TextView设置滤镜数组时需要考虑滤镜的顺序。

关于Android TextView的TextWatcher的用例的详细说明,本文到此为止。关于Android TextView使用TextWatcher的更多信息,请搜索我们之前的文章或继续浏览下面的相关文章。希望你以后能支持我们!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

相关文章阅读

  • windowsandroid手机版下载,windowsandroid安装apk
  • windowsandroid手机版下载,windowsandroid安装apk,WindowsAndroid 安装教程详解
  • android调用webview方法,androidwebview是什么,Android 中 WebView 的基本用法详解
  • android传感器高级编程,Android传感器,Android编程之光线传感器用法详解
  • android.app.Dialog,android自定义dialog对话框,Android开发笔记之-Dialog的使用详解
  • android 图片视频轮播框架,androidlayout轮播图,Android实现炫酷轮播图效果
  • android里的viewpager,安卓自定义view流程,Android自定义引导玩转ViewPager的方法详解
  • android里的viewpager,android viewpager详解
  • android里的viewpager,android viewpager详解,Android自定义超级炫酷的ViewPage指示器
  • android调用webview方法,androidwebview是什么
  • android设置控件宽度,android获取屏幕宽度和高度
  • android设置控件宽度,android获取屏幕宽度和高度,Android中获取控件宽高的4种方法集合
  • android蓝牙开发的基本流程,安卓蓝牙app开发教程
  • android蓝牙开发的基本流程,安卓蓝牙app开发教程,android蓝牙简单开发示例教程
  • android菜单栏,android菜单控件
  • 留言与评论(共有 条评论)
       
    验证码: