安卓onTextChanged参数解释及实现EditText字数监听 Editable使用
尊重原作者:此篇文章是借鉴原作者地址 的博文 并进行修改和增加补充说明,我只是补充和修改:
我感觉这篇文章经过我的补充 市面多少文本操作变化 你都知道怎么做了.并且感觉是非常详细关于 android 文本编辑框的文本变化 并且通俗易懂(内含动态图),
为了大家方便查看 我这里复制作者博文内容 并且修正部分内容 后面在补充
我正参加CSDN明日之星比赛 还希望您投我一票
原作者部分(修改部分)
由于最近做项目要检测EditText中输入的字数长度,从而接触到了Android中EditText的监听接口,TextWatcher。
它有三个成员方法,第一个after很简单,这个方法就是在EditText内容已经改变之后调用,重点看下面两个方法:
beforeTextChanged(CharSequence s, int start, int count, int after)
这个方法是在Text改变之前被调用,它的意思就是说在原有的文本s中,从start开始的count个字符将会被一个新的长度为after的文本替换,注意这里是将被替换,还没有被替换。
onTextChanged(CharSequence s, int start, int before, int count)
这个方法是在Text改变过程中触发调用的,它的意思就是说在原有的文本s中,从start开始的count个字符替换长度为before的旧文本,注意这里没有将要之类的字眼,也就是说一句执行了替换动作。
可能说起来比较抽象,我举个简单的例子,比如说我们监听一个EditText,默认开始的时候EditText中没有文本,当我们输入LOVE四个字母的时候,在打印信息中我输出各个参数看一下参数的变化。
10-18 16:40:21.528: D/Debug(4501): beforeTextChanged 被执行----> s=----start=0----after=1----count=0
10-18 16:40:21.528: D/Debug(4501): onTextChanged 被执行---->s=L----start=0----before=0----count=1
10-18 16:40:21.532: D/Debug(4501): afterTextChanged 被执行---->L
10-18 16:40:29.304: D/Debug(4501): beforeTextChanged 被执行----> s=L----start=1----after=1----count=0
10-18 16:40:29.308: D/Debug(4501): onTextChanged 被执行---->s=LO----start=1----before=0----count=1
10-18 16:40:29.308: D/Debug(4501): afterTextChanged 被执行---->LO
10-18 16:40:32.772: D/Debug(4501): beforeTextChanged 被执行----> s=LO----start=2----after=1----count=0
10-18 16:40:32.772: D/Debug(4501): onTextChanged 被执行---->s=LOV----start=2----before=0----count=1
10-18 16:40:32.776: D/Debug(4501): afterTextChanged 被执行---->LOV
10-18 16:40:34.772: D/Debug(4501): beforeTextChanged 被执行----> s=LOV----start=3----after=1----count=0
10-18 16:40:34.772: D/Debug(4501): onTextChanged 被执行---->s=LOVE----start=3----before=0----count=1
10-18 16:40:34.776: D/Debug(4501): afterTextChanged 被执行---->LOVE
通过上面的打印信息我们可以发现在输入L之前beforeTextChanged被执行,s为空,所以s输入空,start=0,也就是从位置0开始,count=0,也就是0个字符将会被替换,after=1,也就是说0个字符将会被一个新的长度为after=1的文本(也就是L)替换。
当输入发生改变的时候onTextChanged被执行,此时s=L也就是输入的字母L,从start=0开始,count=1个字符替换了长度为before=0的旧文本。通俗点将就是字母L从位置0开始替换了原来的空文本,下面的就可以依次类推了。那么我们如何利用这个接口监听EditText的文本变化来实现限制输入字数的功能呢,我相信大家都有自己的想法了,这里我给出自己的一个简单实现,主要代码如下:
source_des.addTextChangedListener(new TextWatcher() {
private CharSequence temp;
private int selectionStart;
private int selectionEnd;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d(TAG, "onTextChanged 被执行---->s=" + s + "----start="+ start
+ "----before="+before + "----count" +count); temp = s;
}
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
Log.d(TAG, "beforeTextChanged 被执行----> s=" + s+"----start="+ start
+ "----after="+after + "----count" +count);
}
public void afterTextChanged(Editable s) {
Log.d(TAG, "afterTextChanged 被执行---->" + s);
//获取光标开始的位置
selectionStart = source_des.getSelectionStart();
//获取光标结束的位置
selectionEnd = source_des.getSelectionEnd();
//这里其实selectionStart == selectionEnd
// 大家可以把获取的位置放入beforeTextChanged 然后选择部分文字(选择部分位置用光标选择2个以上) 删除可以看到效果 我后面做实验
if (temp.length() > MAX_LENGTH) {
Toast.makeText(MainActivity.this, "只能输入九个字",
Toast.LENGTH_SHORT).show();
//删除部分字符串 为[x,y) 包含x位置不包含y
//也就是说删除 位置x到y-1
s.delete(selectionStart - 1, selectionEnd);
int tempSelection = selectionEnd;
//这里我修改了原作者 不需要这部
//source_des.setText(s);
//如果你setText 传入s 的话会将编辑框的光标移到文本框最前面 所以这里我也注释了原作者
//source_des.setSelection(tempSelection);
}
}
});
补充部分
好了大家看到了增加文本动态监听 那么我们看看删除会怎么触发事件
实验代码:
editText.addTextChangedListener(new TextWatcher() {
private CharSequence temp;
private int selectionStart;
private int selectionEnd;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d(TAG, "onTextChanged 被执行---->s=" + s + "----start="+ start
+ "----before="+before + "----count" +count); temp = s;
Log.e(TAG, "onTextChanged--getSelectionStart: " + editText.getSelectionStart());
Log.e(TAG, "onTextChanged---getSelectionEnd: " + editText.getSelectionEnd());
}
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
Log.d(TAG, "beforeTextChanged 被执行----> s=" + s+"----start="+ start
+ "----after="+after + "----count" +count);
Log.e(TAG, "beforeTextChanged---getSelectionStart: " + editText.getSelectionStart());
Log.e(TAG, "beforeTextChanged---getSelectionEnd: " + editText.getSelectionEnd());
}
public void afterTextChanged(Editable s) {
Log.d(TAG, "afterTextChanged 被执行---->" + s);
selectionStart = editText.getSelectionStart();
selectionEnd = editText.getSelectionEnd();
Log.e(TAG, "afterTextChanged---getSelectionStart: " + editText.getSelectionStart());
Log.e(TAG, "afterTextChanged---getSelectionEnd: " + editText.getSelectionEnd());
}
});
我们这里输入LOVE然后删除’ov’两个字母看看会发生
动态图显示步骤:
可以看到我把光标放入ov外面 那么光标开始位置为1 ,结束位置为3.然后删除
我们看看日志
12-03 12:20:22.355 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被执行----> s=love----start=1----after=0----count2
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 1
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 12:20:22.359 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被执行---->s=le----start=1----before=2----count0
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 1
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 1
12-03 12:20:22.412 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被执行---->le
12-03 12:20:22.412 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 1
12-03 12:20:22.412 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 1
这里我放一张有颜色区分图片 (和上面一样的 只不过方便大家查看)
我们先来看看beforeTextChanged的日志部分
12-03 12:20:22.355 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被执行----> s=love----start=1----after=0----count2
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 1
12-03 12:20:22.355 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
s:文字没有改变前字符串
start:准备要变化文本的位置下标 ,我们这里选择’ov’位置 所以这里相对应’love’位置为1
count:相对没改变前旧文本文本减少数量 因为我们这里要删除’ov’所以为2
after:新文本新加入的字符数量 这里没有增加反而减少 所以为0
getSelectionStart:我们光标的位置不是o的左边吗?所以为1
getSelectionEnd:光标位置在v右边 所以为3 大家回去看下动态图
我们最后来看一下另外onTextChanged
这部分的日志如下:
12-03 12:20:22.359 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被执行---->s=le----start=1----before=2----count0
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 1
12-03 12:20:22.359 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 1
s:被改变后的文本 因为我们这里删除删除’ov’ 所以为le
start:文本开始改变的位置 ‘ov’相对原本文本的开始位置1,所以这里返回1
before:改变之前旧文本减少的数量 这里 ‘love’减少 ‘ov’相当于减少了2
count:新文本添加数量 这里是减少2所以返回0
getSelectionStart 这里删除后的光标状态 所以等于1
getSelectionEnd 这里删除后的光标状态 所以开始坐标等结束坐标 因此等于1
补充部分2
我们假设剪切板内容’12’ (意思是说我们赋值了12字符串在剪切板,只要一粘贴就会出现’12’)
那么我们做一个实验 在love上 用光标选择’ov’ 然后粘贴’12’
动态图(大家耐心等下):
这里日志为:
12-03 12:51:25.347 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被执行----> s=love----start=1----after=2----count2
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 12:51:25.348 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被执行---->s=l12e----start=1----before=2----count2
12-03 12:51:25.348 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 3
12-03 12:51:25.348 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 3
12-03 12:51:25.378 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被执行---->l12e
12-03 12:51:25.378 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 3
12-03 12:51:25.379 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 3
这里我就简单说下光标位置的问题:因为替换相同长度的文本 所以光标并没有移动 位于选择的字符串+1的 位置 ,我们这里选择’ov’ 所以开始和结束为:3 (o的位置)
beforeTextChanged 日志解释:
12-03 12:51:25.347 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被执行----> s=love----start=1----after=2----count2
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 12:51:25.347 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
start:文本开始位置,因为我们从’ov’的’o’开始改变所以为1(love中o不是相对是1嘛)
after:新文本增加的数量 因为增加了12所以两个字符就是2
count:原本旧字符串减少的数量 减少’ov’所以是2
其他的同学们可以自己推断
补充部分3
这里我们再看看替换不同长度的文本
我们这里 光标选择’ov’ 替换为’12345’(剪切板以保存)
12-03 13:01:25.735 21082-21082/a.fmy.com.test D/FMY: beforeTextChanged 被执行----> s=love----start=1----after=5----count2
12-03 13:01:25.735 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionStart: 3
12-03 13:01:25.735 21082-21082/a.fmy.com.test E/FMY: beforeTextChanged---getSelectionEnd: 3
12-03 13:01:25.737 21082-21082/a.fmy.com.test D/FMY: onTextChanged 被执行---->s=l12345e----start=1----before=2----count5
12-03 13:01:25.737 21082-21082/a.fmy.com.test E/FMY: onTextChanged--getSelectionStart: 6
12-03 13:01:25.737 21082-21082/a.fmy.com.test E/FMY: onTextChanged---getSelectionEnd: 6
12-03 13:01:25.770 21082-21082/a.fmy.com.test D/FMY: afterTextChanged 被执行---->l12345e
12-03 13:01:25.770 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionStart: 6
12-03 13:01:25.770 21082-21082/a.fmy.com.test E/FMY: afterTextChanged---getSelectionEnd: 6
可以 替换字符串的时候光标 开始等于结束的
补充部分4 Editable
我们想直接操作文本编辑框的文本的时候 想快速插入和添加 可以考虑这个方法
我们看看两个例子 获取 文本编辑框中的字符串并且添加 ‘你好’在后面;
不使用Editable
String s = editText.getText().toString();
s +="你好";
editText.setText(s);
来我们看看使用Editable
editText.getText().append("你好");
我们看看怎么获取Editable
非常简单只需要用文本编辑框调用getText()方法Editable text = editText.getText();相关API
在文本编辑框后面添加字符串Editable editable = editText.getText();
editable.append("你好");删除文本编辑框部分内容,假设你此时文本编辑框的内容’love’你想删除中间的ov
Editable editable = editText.getText();
//start为要删除文本的开始下标 end为结束下标(不包括)
//也就是说 [start,end)
//editable.delete(start,end);
//注意end必须等于start 不然奔溃
// 也就是 end>=start
//我们看看删除love 中的ov
editable.delete(1,3);在文本编辑框中字符串的某个部分插入字符,假设我们的文本编辑框内容为’love’那么我们想插入 ‘a’到’o’后面也就是’loave’
Editable editable = editText.getText();
String a = "a";
//love 插入o后面 o位置相对于字符的1
//第一个参数 插入 的位置
// 第二个参数 要插入字符串
// 第三个参数 插入的字符串的开始位置
// 第四个参数 插入的字符串的结束位置(不包含)
editable.insert(1,"a",0,a.length());
// 下面方法和上面的等价
//editable.insert(1,"a");
删除文本编辑框所有内容
Editable editable = editText.getText();
editable.clear();
替换文本编辑框部分内容
假设我们将文本框 ‘love’中”o”替换为”a” 也就是说’lave’
Editable editable = editText.getText();
//第一个参数 替换位置
//第二个 替换结束为止(不包含)
//第三个 替换的字符串
editable.replace(1,2,"a");
String a = "a";
//第一个参数 替换位置
//第二个 替换结束为止(不包含)
//第三个 替换的字符串
//第四个 替换文本的开始位置
//第五个 替换文本结束位置 不包含
editable.replace(1,2,"a",0,a.length());
安卓onTextChanged参数解释及实现EditText字数监听 Editable使用的更多相关文章
- onTextChanged参数解释及实现EditText字数监听
http://www.picksomething.cn/?p=34 由于最近做项目要检测EditText中输入的字数长度,从而接触到了Android中EditText的监听接口,TextWatcher ...
- Android addTextChangedListener(文本监听)参数解释及实现EditText字数监听
由于最近做项目要检测EditText中输入的字数长度,从而接触到了Android中EditText的监听接口,TextWatcher.它有三个成员方法,第一个after很简单,这个方法就是在EditT ...
- Android EditText内容监听
监听 EditText的内容变化,作出对应的处理. MainActivity.class package com.example.edittextdemo; import android.app.Ac ...
- Android 实现对多个EditText的监听
create_account=(EditText)findViewById(R.id.create_account); create_password=(EditText)findViewById(R ...
- EditText获取焦点监听事件_EditText获取和失去焦点操作
今天在做搜索框的时候.遇到需要获取焦点之后做一些事情.实现方法也很简单.那就是绑定OnFocusChangeListener事件.实现 onFocusChange(View v, boolean ha ...
- 安卓笔记-- ListView点击和长按监听
其中点击监听为setOnItemClickListener() 具体实现代码如下 listView.setOnItemClickListener(new AdapterView.OnItemClick ...
- textarea增加字数监听且高度自适应(兼容IE8)
1.封装方法: var textareaListener = { /*事件监听器兼容 * *attachEvent——兼容:IE7.IE8:不兼容firefox.chrome.IE9.IE10.IE1 ...
- memcached参数解释及常用命令
一.执行 memcached -h 会显示所有的参数项,对应的中文解释如下: -p <num> 监听的TCP端口(默认: 11211) -U <num> 监 ...
- 监听EditText的变化
http://liangruijun.blog.51cto.com/3061169/729505 之前博客上的有关EditText的文章,只是介绍EditText的一些最基本的用法,这次来深入学习一下 ...
随机推荐
- Spring(六):Spring&Struts2&Hibernate搭建的blog项目
经过断断续续的学习.累积,终于基于别人的开源blog项目,变成了自己的第一个相对完整点的blog项目. 计划暂时把这个blog程序暂停------有更多(工作中用到的)东西需要去做,因此学习SSH b ...
- POJ-3255 Roadblocks---Dijkstra队列优化+次短路
题目链接: https://vjudge.net/problem/POJ-3255 题目大意: 给无向图,求1到n的次短路长度 思路: 由于边数较多,应该使用dijkstra的队列优化 用d数组存储最 ...
- 完成 bass 库的频谱显示效果图
效果如图所示,比 bass 官方自带的例子效果要好那么一点点(峰值有滞留)...
- MongoDB 分片集群搭建
一.概述 分片是一种在多台机器上分配数据的方法.MongoDB使用分片来支持具有非常大的数据集和高吞吐量操作.有两种解决系统增长的方法:垂直扩展和水平扩展. 垂直扩展涉及增加单个服务器的容量,例如使用 ...
- 电力 Web SCADA 工控组态编辑器
前言 SVG 并非仅仅是一种图像格式, 由于它是一种基于 XML 的语言,也就意味着它继承了 XML 的跨平台性和可扩展性,从而在图形可重用性上迈出了一大步.如 SVG 可以内嵌于其他的 XML 文档 ...
- 两个css之间的切换
需求: 头部两个按钮 两种样式之间的切换 解决办法: 结合JQ 三目运算 来处理 第一步: 把需要切换的样式设置为样式里背景,这样做的目的为了避免 js里出现过多 css代码 二来这样会显得更加的清 ...
- 再谈angularJS数据绑定机制及背后原理—angularJS常见问题总结
这篇是对angularJS的一些疑点回顾,是对目前angularJS开发的各种常见问题的整理汇总.如果对文中的题目全部了然于胸,觉得对整个angular框架应该掌握的七七八八了.希望志同道合的通知补充 ...
- 【BZOJ2242】【SDOI2011】计算器
Description 你被要求设计一个计算器完成以下三项任务: 1.给定y.z.p,计算y^z mod p 的值: 2.给定y.z.p,计算满足xy ≡z(mod p)的最小非负整数x: 3.给定y ...
- 【bzoj4444 scoi2015】国旗计划
题目描述 A 国正在开展一项伟大的计划 —— 国旗计划.这项计划的内容是边防战士手举国旗环绕边境线奔袭一圈.这项计划需要多名边防战士以接力的形式共同完成,为此,国土安全局已经挑选了 NN 名优秀的边防 ...
- [BZOJ]1069: [SCOI2007]最大土地面积
题目大意:给出二维平面上n个点,求最大的由这些点组成的四边形面积.(n<=2000) 思路:求出凸包后旋转卡壳枚举对踵点对作为四边形的对角线,枚举或二分另外两个点,复杂度O(n^2)或O(nlo ...