前言

EditText是大家比较熟悉的输入框控件,我们长按,可以使用系统自带的复制粘贴功能;另外获得焦点后,也能和输入法进行交互,实现文字的输入!
如果一个EditText,没有设置任何style,我们想在粘贴显示之前,做一些逻辑上的操作,比如一段文字是粗体或者倾斜的,我想粘贴过来也是粗体或者倾斜,该怎么做!还有如果我们想在输入法输入文字时,就想让输入法输入的文字是粗体或者倾斜的展示在EditText上,又该如何处理!
下边就这两种情况,说一下我解决的方案!
我们知道EditText是继承于TextView的,它本身并没有多少代码,大部分逻辑都是在TextView中的!

定制粘贴

首先,TextView有一个回调方法:onTextContextMenuItem(int id),这个方法就是用来处理系统复制粘贴事件的!所以我们通过重写这一方法来实现定制!这里以设置文字为粗体为例:
我们新建类MyNormalEditText继承EditText

@Overridepublic boolean onTextContextMenuItem(int id) {if (id == android.R.id.paste) {//只设置粘贴文本int lastCursorPosion=getSelectionStart();//拿到粘贴板的文本,setSpan的时候第二个参数last+文本的长度ClipboardManager clip = (ClipboardManager)getContext().getSystemService(Context.CLIPBOARD_SERVICE);String text=clip.getPrimaryClip().getItemAt(0).getText().toString();//之后,设置光标的时候,填这第二个参数即可super.onTextContextMenuItem(android.R.id.paste);SpannableString ss=new SpannableString(getText());//这里之所以分两种情况是因为android系统的粘贴,为了用户体验,会在粘贴的文本前后加上空格,表示是粘贴的内容//如果在文本中间粘贴,会在粘贴文本前后都加上空格;如果在文末粘贴,会在粘贴文本前加上空格;如果空的内容中粘贴,则不加空格if(lastCursorPosion!=0){ss.setSpan(new StyleSpan(Typeface.BOLD), lastCursorPosion+1, lastCursorPosion+1+text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);setText(ss);setSelection(lastCursorPosion+1+text.length());}else{ss.setSpan(new StyleSpan(Typeface.BOLD), lastCursorPosion, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);setText(ss);setSelection(text.length());}return true;}return super.onTextContextMenuItem(id);}

这里有几个需要注意的地方:
①每一个事件都有一个唯一的id对应,比如粘贴事件的idandroid.R.id.paste
②上边注释也有说明,就是android系统的粘贴,为了用户体验,会在粘贴的文本前后加上空格,表示是粘贴的内容!如果在文本中间粘贴,会在粘贴文本前后都加上空格;如果在文末粘贴,会在粘贴文本前加上空格;如果空的内容中粘贴,则不加空格。
关于这个问题,我们可以在源码中看到,可以参考下面这篇文章:关于EditText选择文字后粘贴出现空格的解决思路
③setSpan()方法的第三个参数,这个不是这篇文章的内容,这里就提一下,可以看一下这篇文章,对这4个不同的参数有一个区分:
android中用Spannable在TextView中设置超链接、颜色、字体
④EditText在调用setText()方法之后,光标会自动跳到最前边,所以最好在粘贴之后设置一下光标的位置!

上边是仅仅对粘贴的文本做了处理,如果输入框中本来有文字则不受影响,如果想粘贴完之后,全部都是粗体:

super.onTextContextMenuItem(android.R.id.paste);
SpannableString ss=new SpannableString(getText());
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, getText().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(ss);
return true;

定制输入

在Android中,输入法和输入框是通过InputConnection这一接口进行交互的,InputConnection算是两者的一个通信的桥梁!
TextView中有一个回调方法:onCreateInputConnection(EditorInfo outAttrs),它返回一个InputConnection对象,所以如果要定制输入,需要重写这一方法!另外需要返回一个InputConnection对象,所以我们要自定义一个类返回,这里我们继承InputConnectionWrapper,这个实现InputConnection接口的类即可!
至于为什么这样就可以了,为什么要继承InputConnectionWrapper,输入法输入的文本怎么展示到EditText上边的,这是android输入法框架的内容,这里就不详细阐述了!
想要了解的童鞋,可以参考这篇文章:
Android输入法框架系统(下)

好了,下边说一下实现方案,还是以设置粗体为例:
首先还是继承EditText,重写onCreateInputConnection()方法,

@Overridepublic InputConnection onCreateInputConnection(EditorInfo outAttrs) {return new MyNormalEditText.MyInputConnection(super.onCreateInputConnection(outAttrs),false);}class MyInputConnection extends InputConnectionWrapper {public MyInputConnection(InputConnection target, boolean mutable) {super(target, mutable);}@Overridepublic boolean commitText(CharSequence text, int newCursorPosition) {SpannableString ss=new SpannableString(text);ss.setSpan(new StyleSpan(Typeface.BOLD), 0, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);super.commitText(ss, newCursorPosition); return true;}}

需要注意的几个问题:
①MyInputConnection构造方法的第二个参数boolean mutable源码中,这一参数就这一个地方有用到,InputConnectionWrapper构造方法中将其赋给了全局变量mMutable:

/*** Change the target of the input connection.*/
public void setTarget(InputConnection target) {if (mTarget != null && !mMutable) {throw new SecurityException("not mutable");}mTarget = target;
}

从字面意思来看Mutable,可变的,setTarget(InputConnection target)传入一个InputConnection ,就是说是否设置InputConnection 可变,我的理解就是一个EditText和输入法就是一个InputConnection,如果在构造方法中传入了一个false,就意味着这个连接不可变!
然而在我们这个功能中,这个参数好像并没有什么卵用啊!

同样的,如果想输入时,全部文本都是粗体的,在commitText()中应该这样写:

//如果想设置全部文本,则要这样写
super.commitText(text, newCursorPosition);
//注意这里cursor已经是下一个字的下标了
int lastCursorPosion = MyNormalEditText.this.getSelectionStart()-1;
SpannableString ss=new SpannableString(getText());
ss.setSpan(new StyleSpan(Typeface.BOLD), 0, getText().length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
setText(ss);
//这里要设置一下光标的位置,是因为EditText#setText()方法后,光标会自动显示在最前边
MyNormalEditText.this.setSelection(lastCursorPosion+newCursorPosition);
return true;

因为,输入字之后,光标要在前一个输入的字的后,所以在setSelection()的时候,传入的位置要特别注意一下!

参考文章:
Android 开发之拦截EditText的输入内容,定制输入内容

Android EditText定制粘贴和定制输入相关推荐

  1. android 输入法不自动弹出窗口,Android EditText默认不弹出输入法的实现方法

    一.Android EditText默认不弹出输入法的办法: 1. 在AndroidManifest.xml中将需要默认隐藏键盘的Activity中添加属性即可(常用此方法) android:wind ...

  2. Android EditText缴获与监听输入事件

    Android EditText缴获与监听输入事件 Android EditText截获与监听输入事件 预期目标:如下图,输入框中每输入一个字符,下面的TextView可以迅速的显示出来输入框中的内容 ...

  3. 关于Android 模拟器复制粘贴及中文输入的问题

    问题 平时开发时候用的Android Studio自带的模拟器调试 ,但应用输入框输入时存在以下两个问题 不支持ctrl+c ctrl+v 方式复制粘贴 默认模式下,不支持中文输入 解决方案 左键长按 ...

  4. android edittext限制字节_android EditText输入限制

    zyz 发表于 2012-5-30 18:19:03 android EditText输入限制 android:digits="1234567890.+-*/%\n()" 限制输入 ...

  5. Android自定义视图四:定制onMeasure强制显示为方形

    这个系列是老外写的,干货!翻译出来一起学习.如有不妥,不吝赐教! Android自定义视图一:扩展现有的视图,添加新的XML属性 Android自定义视图二:如何绘制内容 Android自定义视图三: ...

  6. android edittext输入邮箱,[Android教程]EditText怎样限制用户的输入?数字/字母/邮箱

    有输入必有验证.为了防止用户随便输入确保提交数据的合法性,程序不得不在文本输入框(EditText)中增加限制或验证. 关于输入类型有数字.字母.邮箱.电话等形式,这些具体得根据业务来.那么Andro ...

  7. java edittext 输入监听_Android应用开发之Android EditText 监听用户输入完成的实例

    本文将带你了解Android应用开发Android EditText 监听用户输入完成的实例,希望本文对大家学Android有所帮助. 我们都知道, Android   EditText输入框,并没有 ...

  8. android EditText光标位置,光标样式,EditText限制输入内容,软键盘遮挡的EditText,搜索框,限制输入表情

    显示在软键盘上 android:windowSoftInputMode="adjustPan|stateHidden" 1.光标位置 homesosoedit.setSelecti ...

  9. android设置输入框输入字符限制,Android EditText限制输入字符的方法总结

    Android EditText限制输入字符的方法总结 最近项目要求限制密码输入的字符类型, 例如不能输入中文.   现在总结一下EditText的各种实现方式,  以比较各种方法的优劣. 第一种方式 ...

最新文章

  1. 统计简单学_基本概念
  2. tomcat 多实例启动脚本
  3. python字典随时添加元素和值
  4. ios开发中计算代码运算时间_理解Unity中的优化(二):内存
  5. dell服务器r730老自动重启_Dell R730服务器安装windows server 2008 R2蓝屏问题
  6. un-app uni.navigateTo页面跳转做封装传参
  7. 必收藏的九大塑料注塑成型技术及其特点
  8. FLASH学习(一)
  9. 【opencv-ml】支持向量机简介
  10. 什么!这就是PCB打板!
  11. matlab矩阵保存到表格,将matlab求出的矩阵保存在Excel表格中
  12. 邮箱smtp服务器及端口收集
  13. Java实现 蓝桥杯VIP 算法提高 班级排名
  14. 计算机教师读56 号教室体会,《第56号教室的奇迹》读后感(精选7篇)
  15. window7电脑声音图标不见了
  16. 1024 java学习之路。
  17. 2022安全员-A证考试题模拟考试平台操作
  18. 程序员读书--《谁动了我的奶酪》读后感
  19. 分组背包问题(动态规划法)
  20. nn.Embedding使用

热门文章

  1. 2020工程伦理(清华版)期末考试参考答案
  2. 活动目录数据库文件介绍
  3. MemCache和一致性Hash算法讲解
  4. android版本11下载,android 11正式版下载-android 11正式版系统下载-pk38游戏网
  5. screen命令后台运行程序
  6. 利用busybox, extlinux 在工控机CompactFlash(CF卡)上构建Linux系统(下)
  7. “互联网+”谋定新业态-李玉庭:经信研究重整消费升级
  8. Power BI区域可视化(中国、各省市、各区县)
  9. Typora代码块字体修改
  10. 推荐一些优秀的SAP网站