Android实现登录邮箱的自动补全功能
龙旋
共 3874字,需浏览 8分钟
·
2022-06-07 23:10
Android SDK 提供了MultiAutoCompleteTextView 控件,可以支持从指定字符开始联想,MultiAutoCompleteTextView 通过分词器 Tokenizer,可以支持连续提示
下面是运行效果图:
只要输入“@”符号就会自动联想邮箱。
下面是自定义的 MailBoxAssociateView 类继承于AppCompatMultiAutoCompleteTextView 控件,来实现联想邮箱组件。
/**
* @desciption: 邮箱联想控件,输入 @ 符后开始联想
*/
public class MailBoxAssociateView extends AppCompatMultiAutoCompleteTextView {
public MailBoxAssociateView(Context context) {
super(context);
}
public MailBoxAssociateView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MailBoxAssociateView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
/**
* 当输入@符号时,就会去调用Tokenizer.findTokenStart()方法一次
* 当点击下拉提示框中的某个信息时,会再次调用Tokenizer.findTokenStart()方法一次,然后再调用terminateToken()方法一次
*/
@Override
public boolean enoughToFilter() {
// 若用户输入的文本字符串中包含'@'字符且不在第一位,则满足条件返回true,否则返回false
return getText().toString().contains("@") && getText().toString().indexOf("@") > 0;
}
}
如果需要输入的第一个字符是“@”就联想邮箱只需要改为以下代码即可。
@Override
public boolean enoughToFilter() {
return getText().toString().contains("@") ;
}
自定义分词器 MailBoxAssociateTokenizer 类,指定从哪个地方开始联想字符。
/**
* @desciption: 指定从哪个地方开始联想字符
*/
public class MailBoxAssociateTokenizer implements MultiAutoCompleteTextView.Tokenizer {
/**
* 用于查找当前光标位置之前的分隔符的位置并返回
*
* @param text 用户已经输入的文本内容
* @param cursor 当前光标的位置,在文本内容后面
* @return
*/
@Override
public 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
*/
@Override
public 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
*/
@Override
public 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;
}
}
}
}
布局文件 :
android:id="@+id/associate_email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="57dp"
android:hint="@string/account"
android:paddingLeft="5dp"
android:paddingBottom="12dp"
android:popupBackground="@drawable/bg_recommend_mail_list"
android:singleLine="true"
android:textColor="@color/color_333333"
android:textColorHint="@color/color_bfbfbf"
android:textSize="16sp"/>
使用方式
在 values 中创建 arrays.xml 文件
- \@gmail.com
- \@hotmail.com
- \@yahoo.com
- \@outlook.com
- \@aol.com
- \@hotmail.co.uk
- \@yahoo.co.uk
- \@mail.ru
- \@rediffmail.com
- \@live.com
- \@msn.com
在 Activity中使用
mUserNameAssociateView = findViewById(R.id.associate_email_input);
String[] recommendMailBox = getResources().getStringArray(R.array.recommend_mail_box);
ArrayAdapter
adapter = new ArrayAdapter<>(this, R.layout.item_associate_mail_list, R.id.tv_recommend_mail, recommendMailBox);
mUserNameAssociateView.setAdapter(adapter);
mUserNameAssociateView.setTokenizer(new MailBoxAssociateTokenizer());
到这里就结束啦。
评论