您的位置:首页 > 移动开发 > Android开发

android源码追踪学习 RecipientsEditor

2013-04-12 17:30 190 查看
RecipientsEditor 新建短信时输入收接者的editor,

public class RecipientsEditor extends MultiAutoCompleteTextView {
private int mLongPressedPosition = -1;
private final RecipientsEditorTokenizer mTokenizer;
private char mLastSeparator = ',';

public RecipientsEditor(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.autoCompleteTextViewStyle);
mTokenizer = new RecipientsEditorTokenizer(context, this);
setTokenizer(mTokenizer);
// For the focus to move to the message body when soft Next is pressed
setImeOptions(EditorInfo.IME_ACTION_NEXT);
// Set threshold as 1 CharSequence.
setThreshold(1);
addTextChangedListener(new TextWatcher() {
private Annotation[] mAffected;

public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
mAffected = ((Spanned) s).getSpans(start, start + count,
Annotation.class);
}

public void onTextChanged(CharSequence s, int start,
int before, int after) {
if (before == 0 && after == 1) {    // inserting a character
char c = s.charAt(start);
if (c == ',' || c == ';') {
// Remember the delimiter the user typed to end this recipient. We'll
// need it shortly in terminateToken().
mLastSeparator = c;
}
}
}

public void afterTextChanged(Editable s) {
if (mAffected != null) {
for (Annotation a : mAffected) {
s.removeSpan(a);
}
}

mAffected = null;
}
});
}


RecipientsEditor 继承于 MultiAutoCompleteTextView

可支持输入多个手机号码,每个手机号码用用分隔符分开,有自动完成功能,预置匹配的数据为联系人;



其中RecipientsEditorTokenizer为了找出输入字符串中的分隔符","和“,”

private class RecipientsEditorTokenizer
implements MultiAutoCompleteTextView.Tokenizer {
private final MultiAutoCompleteTextView mList;
private final Context mContext;

RecipientsEditorTokenizer(Context context, MultiAutoCompleteTextView list) {
mList = list;
mContext = context;
}

public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
char c;

while (i > 0 && (c = text.charAt(i - 1)) != ',' && c != ';') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}

return i;
}

public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
char c;

while (i < len) {
if ((c = text.charAt(i)) == ',' || c == ';') {
return i;
} else {
i++;
}
}

return len;
}

public CharSequence terminateToken(CharSequence text) {
int i = text.length();

while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}

char c;
if (i > 0 && ((c = text.charAt(i - 1)) == ',' || c == ';')) {
return text;
} else {
// Use the same delimiter the user just typed.
// This lets them have a mixture of commas and semicolons in their list.
String separator = mLastSeparator + " ";
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + separator);
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + separator;
}
}
}


setImeOptions(EditorInfo.IME_ACTION_NEXT);//设置软键盘右下角的button的功能为下一个,即切换到下一个输入框,如果设置成EditorInfo.IME_ACTION_DONE,则表示输入完成,关掉软键盘,还有很多其他的选项可供设置的
setThreshold(1);// Threshold门槛的意思,此处设置只要输入一个字符就开始匹配,若设置为“2”则表示要输入两个字符才是匹配。

addTextChangedListener(TextWatcher);//添加一个TextView监听器

TextWatcher里有三个回调方法,当有输入框里的字符有变化时会自动依次调用以下三个方法:

beforeTextChanged(CharSequence s, int start,int count, int after) ;

//此处已输入为例解释上面各变量的意思,s 是输入以前的字符串,start光标所在的位置, count为要改变的字符个数,即选中的个数,after为要插入的个数

onTextChanged(CharSequence s, int start, int before, int after)

//s为改变后的字符串,start和上面的start一样, before和上面的count一样,after与上面的after一样

afterTextChanged(Editable s)// s为改变后的字符串

预制匹配数据为联系人的方法是通过设置适配器:

mRecipientsEditor.setAdapter(new RecipientsAdapter(this));
RecipientsAdapter 是extends ResourceCursorAdapter的

在适配器里面通过Phone.CONTENT_FILTER_URI,获取电话本里的信息。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: