Android SDK 提供了MultiAutoCompleteTextView 控件,可以支持从指定字符开始联想。MultiAutoCompleteTextView 通过分词器 Tokenizer,可以支持连续提示 下面是运行效果图:

只要输入“@”符号就会自动联想邮箱。 下面是自定义的 MailBoxAssociateView 类继承于AppCompatMultiAutoCompleteTextView 控件,来实现联想邮箱组件,右边加入删除按钮!

/*** @desciption: 邮箱联想控件,输入 @ 符后开始联想*/public class MailBoxAssociateView extends AppCompatMultiAutoCompleteTextView implements TextWatcher, View.OnTouchListener {// 删除符号Drawable deleteImage = getResources().getDrawable(R.mipmap.icon_close_editext);Drawable icon;public MailBoxAssociateView(Context context) {super(context);init();}public MailBoxAssociateView(Context context, AttributeSet attrs) {super(context, attrs);init();}public MailBoxAssociateView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {MailBoxAssociateView.this.setOnTouchListener(this);MailBoxAssociateView.this.addTextChangedListener(this);deleteImage.setBounds(0, 0, deleteImage.getIntrinsicWidth(), deleteImage.getIntrinsicHeight());manageClearButton();}/*** 传入显示的图标资源id*/public void setIconResource(int id) {icon = getResources().getDrawable(id);icon.setBounds(0, 0, icon.getIntrinsicWidth(), icon.getIntrinsicHeight());manageClearButton();}/*** 传入删除图标资源id*/public void setDeleteImage(int id) {deleteImage = getResources().getDrawable(id);deleteImage.setBounds(0, 0, deleteImage.getIntrinsicWidth(), deleteImage.getIntrinsicHeight());manageClearButton();}private void manageClearButton() {if (this.getText().toString().equals("")) {removeClearButton();} else {addClearButton();}}private void addClearButton() {this.setCompoundDrawables(this.icon, this.getCompoundDrawables()[1], deleteImage,this.getCompoundDrawables()[3]);}private void removeClearButton() {this.setCompoundDrawables(this.icon, this.getCompoundDrawables()[1], null,this.getCompoundDrawables()[3]);}/*** 当输入@符号时,就会去调用Tokenizer.findTokenStart()方法一次* 当点击下拉提示框中的某个信息时,会再次调用Tokenizer.findTokenStart()方法一次,然后再调用terminateToken()方法一次*/@Overridepublic boolean enoughToFilter() {// 若用户输入的文本字符串中包含'@'字符且不在第一位,则满足条件返回true,否则返回falsereturn getText().toString().contains("@") && getText().toString().indexOf("@") > 0;}@Overridepublic void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {}@Overridepublic void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {MailBoxAssociateView.this.manageClearButton();}@Overridepublic void afterTextChanged(Editable editable) {}@Overridepublic boolean onTouch(View view, MotionEvent event) {MailBoxAssociateView et = MailBoxAssociateView.this;if (et.getCompoundDrawables()[2] == null) return false;if (event.getAction() != MotionEvent.ACTION_UP) return false;if (event.getX() > et.getWidth() - et.getPaddingRight() - deleteImage.getIntrinsicWidth()) {et.setText("");MailBoxAssociateView.this.removeClearButton();}return false;}//让EditText变成可编辑状态public void unlock() {setFilters(new InputFilter[]{new InputFilter() {@Overridepublic CharSequence filter(CharSequence source, int start,int end, Spanned dest, int dstart, int dend) {return null;}}});}//让EditText变成不可编辑状态public void lock() {setFilters(new InputFilter[]{new InputFilter() {@Overridepublic CharSequence filter(CharSequence source, int start,int end, Spanned dest, int dstart, int dend) {return source.length() < 1 ? dest.subSequence(dstart, dend): "";}}});}//让EditText变成可编辑状态public void unlockAndManage() {manageClearButton();setFocusableInTouchMode(true);setFilters(new InputFilter[]{new InputFilter() {@Overridepublic CharSequence filter(CharSequence source, int start,int end, Spanned dest, int dstart, int dend) {return null;}}});}Long time ;@Overrideprotected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {super.onFocusChanged(focused, direction, previouslyFocusedRect);if (focused) {time = System.currentTimeMillis();} else {System.out.println("~~~~~~~~~~"+this.getId() + ":" + (System.currentTimeMillis() - time));}}}

如果需要输入的第一个字符是“@”就联想邮箱只需要改为以下代码即可。

@Overridepublic boolean enoughToFilter() {return getText().toString().contains("@") ;}

自定义分词器 MailBoxAssociateTokenizer 类,指定从哪个地方开始联想字符。

/*** @desciption: 指定从哪个地方开始联想字符*/
public class MailBoxAssociateTokenizer implements MultiAutoCompleteTextView.Tokenizer {/*** 用于查找当前光标位置之前的分隔符的位置并返回** @param text   用户已经输入的文本内容* @param cursor 当前光标的位置,在文本内容后面* @return*/@Overridepublic int findTokenStart(CharSequence text, int cursor) {int index = text.toString().indexOf("@");if (index < 0) {index = text.length();}if (index > findTokenEnd(text, cursor)) {index = 0;}return index;}/*** 用于查找当前光标位置之后的分隔符的位置并返回,向后查询** @param text   用户已经输入的文本内容* @param cursor 当前光标的位置,在文本内容之间* @return*/@Overridepublic int findTokenEnd(CharSequence text, int cursor) {int i = cursor;int len = text.length();// 向后查找'@'字符,若找到则直接返回其所在位置while (i < len) {if (text.charAt(i) == '@') {return i;} else {i++;}}return len;}/*** 用于返回提示信息加上分隔符后的文本内容** @param text* @return*/@Overridepublic CharSequence terminateToken(CharSequence text) {int i = text.length();//去掉原始匹配的数据的末尾空格while (i > 0 && text.charAt(i - 1) == ' ') {i--;}//判断原始匹配的数据去掉末尾空格后是否含有'@',有则立即返回if (i > 0 && text.charAt(i - 1) == '@') {return text;} else {// CharSequence类型的数据有可能是富文本SpannableString类型// 故需要进行判断if (text instanceof Spanned) {SpannableString sp = new SpannableString(text);// 故需要借助TextUtils.copySpansFrom从text中复制原来的样式到新的sp中,// 以保持原先样式不变情况下添加一个逗号和空格TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);return sp;}else {return text;}}}
}

布局文件 :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"tools:context=".MultiAutoTextActivity"><com.example.a31210.mypermissions.view.MailBoxAssociateViewandroid:id="@+id/associate_email_input"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="57dp"android:paddingLeft="5dp"android:paddingBottom="12dp"android:singleLine="true"android:textColor="#333333"android:textSize="16sp"/></LinearLayout>

在 values 中创建 arrays.xml 文件

<?xml version="1.0" encoding="utf-8"?>
<resources><string-array name="recommend_mail_box"><!--@对应@--><item>\@gmail.com</item><item>\@hotmail.com</item><item>\@yahoo.com</item><item>\@outlook.com</item><item>\@aol.com</item><item>\@hotmail.co.uk</item><item>\@yahoo.co.uk</item><item>\@mail.ru</item><item>\@rediffmail.com</item><item>\@live.com</item><item>\@msn.com</item></string-array>
</resources>

在 Activity中使用

public class MultiAutoTextActivity extends AppCompatActivity {
private MailBoxAssociateView mUserNameAssociateView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_multi_auto_text);mUserNameAssociateView = findViewById(R.id.associate_email_input);String[] recommendMailBox = getResources().getStringArray(R.array.recommend_mail_box);ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, recommendMailBox);mUserNameAssociateView.setAdapter(adapter);mUserNameAssociateView.setTokenizer(new MailBoxAssociateTokenizer());}
}

Android实现登录邮箱的自动补全功能相关推荐

  1. html邮箱下拉栏,jQuery实现邮箱下拉列表自动补全功能

    记得,在上个项目中,遇到这样一个需求,网站要求填写邮箱的时候,还没有填写完,就会出现一系列下拉列表,帮助自动补全邮箱的功能.今天小编给给大家分享下我基于jquery是怎么实现此功能的! 功能简述 •填 ...

  2. 仿新浪微博登录的邮箱地址自动补全功能

    首先,来看一下登录新浪微博的效果图: 当你开始输入你的电子邮箱前的帐号时,就会出现常用邮箱的列表,并自动补齐. 实现的时候,首先在页面上放一个输入文本框和一个div.将div隐藏: 电子邮件:< ...

  3. Chrome for Android AutoComplete地址栏地址自动补全功能调研和更新

    Chrome地址栏地址自动补全功能调研和更新 我的博客对应文章地址 Chrome地址栏地址自动补全功能预览 补全前提: 1. 使用Gboard输入法 2. Gboard输入法打开了[文字更正]功能里面 ...

  4. linux 函数自动补全,Shell脚本中实现自动补全功能

    对于Linuxer来说,自动补全是再熟悉不过的一个功能了.当你在命令行敲下部分的命令时,肯定会本能地按下Tab键补全完整的命令,当然除了命令补全之外,还有文件名补全. Bash-completion ...

  5. linux下 为自己编写的程序 添加tab自动补全 功能

    linux下 为自己编写的程序 添加tab自动补全功能 入门 complete 在我的tmp下随便写了一个a.sh, 为他补全 edit /etc/bash_completion.d/foo _foo ...

  6. 转:Eclipse自动补全功能轻松设置

    Eclipse自动补全功能轻松设置 || 不需要修改编辑任何文件 2012-03-08 21:29:02|  分类: Java |  标签:eclipse  自动补全  设置  |举报|字号 订阅 下 ...

  7. Jupyter Notebook 代码自动补全功能

    调试记录 第一步 第二步 第三步 第四步 第一步 打开如下命令行 第二步 输入如下命令 conda info --envs 可以看到现在是基础(base)环境,我是想进入tensorflow环境 输入 ...

  8. gocode+auto-complete搭建emacs的go语言自动补全功能

    上篇随笔记录了在emacs中使用go-mode和goflymake搭建了go语言的简单编程环境(推送门),今天来记录一下使用gocode+auto-complete配置emacs中go语言的自动补全功 ...

  9. python shell怎么调字体_Python3设置在shell脚本中自动补全功能的方法

    本篇博客将会简短的介绍,如何在ubuntu中设置python自动补全功能. 需求:由于python中的内建函数较多,我们在百纳乘时,可能记不清函数的名字,同时自动补全功能,加快了我们开发的效率. 方法 ...

最新文章

  1. 一段文字讲清楚Kubernetes的工作原理
  2. jq输出文本_jQuery获取文本节点之 text()/val()/html() 方法区别
  3. 易开发创始人潘俊勇:这些年我遇到的那些坑
  4. Linq 多表连接查询join
  5. Css中Position属性的含义
  6. 业务专题篇:AB测试实验设计与评估
  7. office professional 2010 key
  8. 可编程的智能小车,100种玩法,让孩子玩出理科编程思维
  9. Bootstrap 标签页Tab插件的事件
  10. java实现单链表常见操作,java面试题,java初级笔试题
  11. Uniswap 24h交易量约11.2亿美元涨23.91%
  12. halcon中的面向对象,数据保存(续)
  13. Confluent修改许可,限制其他云供应商
  14. 网易云热评 《十年》
  15. 第一章 核磁共振的物理学基础
  16. AntV X6源码简析
  17. mysql引用表无效列_Mysql使用索引可能失效的场景
  18. C语言经典问题——兑换硬币
  19. PS做以图片为文字背景
  20. 系统服务器可以关机吗,服务器每天关机可以吗

热门文章

  1. 海康服务器系统装不上,ivms-4200客户端登入不了云服务器
  2. Android 面部识别之二(调用开源面部识别算法seetaface检测)
  3. DevOps开发运维:Buddy中文版正式发布
  4. 一览各类无人飞机设计方法
  5. [31期] 31期战地日记
  6. NO.90——京东用户购买意向预测之数据预处理
  7. python 按条件筛选行_Python之根据条件筛选特定行
  8. Ant入门教程(上)
  9. 【超超超详细mysql下载安装攻略(有手就行)】
  10. c#构造函数 例子学习