实现的效果如下:
当用户输入‘@’之后,根据邮箱前缀自动填充后面的内容。
基本原理:
其实就是两个EditView叠加在一起,前后的EditView颜色值不同,其他的所有属性设置都相同。
代码如下:
import android.content.Context;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.EditText;
import android.widget.FrameLayout;
public class EmailTextView extends FrameLayout implements TextWatcher {
private EditText mBgText;
private EditText mFrontText;
private CharSequence mHintText = "";
private int mFirstAtIndex;
private String EMAILS[] = {"qq.com", "126.com", "gmail.com",
"hotmail.com", "163.com", "yahoo.com", "yahoo.com.cn", "sina.com",
"sohu.com", "fenqile.com", "yeah.net", "foxmail.com", "icloud.com",
"live.com", "msn.com", "outlook.com", "tom.com", "vip.qq.com",
"zhihu.com", "sogou.com"};
private AttributeSet mAttrs;
public EmailTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
this.mAttrs = attrs;
init();
}
public EmailTextView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public EmailTextView(Context context) {
super(context);
init();
}
private TextWatcher mTextWatcher;
private void init() {
setPadding(0, 0, 0, 0);
mBgText = new EditText(getContext(), mAttrs);
mBgText.setEnabled(false);
mBgText.setCursorVisible(false);
mBgText.setFocusable(false);
mBgText.setFocusableInTouchMode(false);
mFrontText = new EditText(getContext(), mAttrs);
mFrontText.setBackgroundColor(0x00000000);
addView(mBgText);
addView(mFrontText);
mFrontText.addTextChangedListener(this);
mFrontText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
String bgText = mBgText.getText().toString();
if (!hasFocus) {
if (bgText.equals(mHintText)) {
mFrontText.setText("");
} else {
mFrontText.setText(mBgText.getText().toString());
}
}
}
});
mFrontText.setImeOptions(EditorInfo.IME_ACTION_NEXT);
requestFocus();
mFrontText.requestFocus();
}
public void setHintTextColor(int color) {
mBgText.setTextColor(color);
}
public void setTextColor(int color) {
mFrontText.setTextColor(color);
}
public void setHintText(CharSequence s) {
this.mHintText = s;
if (mBgText.getText().length() == 0) {
mBgText.setText(s);
}
}
/**
* Change the editor type integer associated with the text view, which will
* be reported to an IME with {@link EditorInfo#imeOptions} when it has
* focus.
*
* @see android.view.inputmethod.EditorInfo
*/
public void setImeOptions(int imeOptions) {
mFrontText.setImeOptions(imeOptions);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
if (mTextWatcher != null) {
mTextWatcher.beforeTextChanged(s, start, count, after);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() == 0) {
mBgText.setText(mHintText);
} else {
String str = s.toString();
mFirstAtIndex = str.indexOf("@");
if (mFirstAtIndex < 0) {
mBgText.setText(s + "@" + EMAILS[0]);
} else {
mBgText.setText(s.subSequence(0, mFirstAtIndex + 1)
+ findEmailSuffix(str.substring(mFirstAtIndex + 1)));
}
}
if (mTextWatcher != null) {
mTextWatcher.onTextChanged(s, start, before, count);
}
}
@Override
public void afterTextChanged(Editable s) {
if (mTextWatcher != null) {
mTextWatcher.afterTextChanged(s);
}
}
public String findEmailSuffix(String start) {
for (String str : EMAILS) {
if (str.startsWith(start)) {
return str;
}
}
return start;
}
public Editable getText() {
return mFrontText.getText();
}
public void setText(CharSequence cs) {
mBgText.setText(cs);
mFrontText.setText(cs);
}
public void addTextChangedListener(TextWatcher tw) {
this.mTextWatcher = tw;
}
public void setTextSize(int sp) {
mFrontText.setTextSize(TypedValue.COMPLEX_UNIT_SP, sp);
mBgText.setTextSize(TypedValue.COMPLEX_UNIT_SP, sp);
}
public boolean requestFocused() {
boolean b = requestFocus();
mFrontText.requestFocus();
return b;
}
}
该组件可以直接在XML里使用,当它是EditView就是了。