项目要求:
登陆界面输入邮箱,自动匹配常用邮箱并自动补全后缀。
比如邮箱为[email protected],当我输入10376129@q时,输入框自动补全后面的q.com且颜色为灰浅色,输入框失去焦点时,补全q.com颜色变为黑色,和前面103796129@q的颜色一致。
解决:
1.通过查看知乎的布局,发现没有用自定义控件,仅仅用了普通的EditText。
2.查看EditTex(继承TextView)t的API,最终想到了用下面这个方法
void android.widget.TextView.setCompoundDrawables(Drawable left,Drawable top, Drawable right,Drawable bottom)
通过绘制EditText右边的Drawable来显示需要自动补全的字符串
3.演示
4.关键代码
package com.lt.autoemailactivity;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.View.OnFocusChangeListener;
import android.widget.EditText;
public class AutoCompleteEditTextActivity extends Activity implements
TextWatcher {
/**
* 邮箱EditText
*/
private EditText mEmailEditText;
/**
* 常用的邮箱
*/
private HashMap mAutoData = new HashMap();
/**
* 邮箱editText的高度
*/
private int mHeight;
/**
* 邮箱editText的宽度
*/
private int mWidth;
/**
* 输入框中字符的baseLine
*/
private int baseLine;
/**
* 画笔
*/
private Paint mPaint;
private Bitmap mBitmap;
/**
* 画布
*/
private Canvas canvas;
private Drawable drawable;
/**
* 后缀字符串
*/
private String mAddedText = "";
/**
* 记录是否为空
*/
private boolean mFlag;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_auto_complete_edittext);
initEmail();
mEmailEditText = (EditText) findViewById(R.id.email);
mEmailEditText.addTextChangedListener(this);
mEmailEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
mEmailEditText.append(mAddedText);
}
}
});
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
String text = s.toString();
mFlag = true;
Iterator> iterator = mAutoData.entrySet()
.iterator();
// 遍历常用邮箱
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
if (text.endsWith(entry.getKey())) {
drawAddedText(entry.getValue());
mAddedText = entry.getValue();
mFlag = false;
break;
}
}
// 如果没有匹配,就画一个空
if (mFlag) {
drawAddedText("");
mAddedText = "";
}
}
/**
* 画出后缀字符串
*
* @param addedText
*/
private void drawAddedText(String addedText) {
// 如果字符串为空,画空
if (addedText.equals("")) {
mEmailEditText.setCompoundDrawables(null, null, null, null);
return;
}
// 只需要初始化一次
if (mBitmap == null) {
mHeight = mEmailEditText.getHeight();
mWidth = mEmailEditText.getWidth();
// 初始化画笔
mPaint = new Paint();
mPaint.setColor(Color.GRAY);
mPaint.setAntiAlias(true);// 去除锯齿
mPaint.setFilterBitmap(true);// 对位图进行滤波处理
mPaint.setTextSize(mEmailEditText.getTextSize());
}
// 计算baseLine
Rect rect = new Rect();
int baseLineLocation = mEmailEditText.getLineBounds(0, rect);
baseLine = baseLineLocation - rect.top;
// 添加的字符窜的长度
int addedTextWidth = (int) (mPaint.measureText(addedText) + 1);
// 创建bitmap
mBitmap = Bitmap.createBitmap(addedTextWidth, mHeight,
Bitmap.Config.ARGB_8888);
canvas = new Canvas(mBitmap);
// 绘制后缀字符串
canvas.drawText(addedText, 0, baseLine, mPaint);
// bitmap转化为Drawable
drawable = new BitmapDrawable(mBitmap);
String text = mEmailEditText.getText().toString();
// 计算后缀字符串在输入框中的位置
int addedTextLeft = (int) (mPaint.measureText(text) - mWidth + addedTextWidth);
int addedTextRight = addedTextLeft + addedTextWidth;
int addedTextTop = 0;
int addedTextBottom = addedTextTop + mHeight;
// 设置后缀字符串位置
drawable.setBounds(addedTextLeft, addedTextTop, addedTextRight,
addedTextBottom);
// 显示后缀字符串
mEmailEditText.setCompoundDrawables(null, null, drawable, null);
}
/**
* 初始化常用的邮箱
*/
private void initEmail() {
mAutoData.put("@q", "q.com");
mAutoData.put("@qq", ".com");
mAutoData.put("@qq.", "com");
mAutoData.put("@qq.c", "om");
mAutoData.put("@qq.co", "m");
mAutoData.put("@1", "63.com");
mAutoData.put("@16", "3.com");
mAutoData.put("@163", ".com");
mAutoData.put("@163.", "com");
mAutoData.put("@163.c", "om");
mAutoData.put("@163.co", "m");
mAutoData.put("@s", "ina.cn");
mAutoData.put("@si", "na.cn");
mAutoData.put("@sin", "a.cn");
mAutoData.put("@sina", ".cn");
mAutoData.put("@sina.", "cn");
mAutoData.put("@sina.c", "n");
mAutoData.put("@s", "ina.com");
mAutoData.put("@si", "na.com");
mAutoData.put("@sin", "a.com");
mAutoData.put("@sina", ".com");
mAutoData.put("@sina.", "com");
mAutoData.put("@sina.c", "om");
mAutoData.put("@sina.co", "m");
mAutoData.put("@1", "26.com");
mAutoData.put("@12", "6.com");
mAutoData.put("@126", ".com");
mAutoData.put("@126.", "com");
mAutoData.put("@126.c", "om");
mAutoData.put("@126.co", "m");
}
}
=======================================分割线====================================================
修改代码结构,讲邮箱自动补全代码封装到EditText中,更方便使用,代码如下:
AutoCompleteEditText.java:
package com.lt.flowlayoutDemo;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.widget.EditText;
public class AutoCompleteEditText extends EditText implements TextWatcher {
private Bitmap mBitmap;
private int mHeight;
private int mWidth;
private Paint mPaint;
private int mBaseLine;
private Canvas mCanvas;
private BitmapDrawable mDrawable;
private boolean mFlag;
private String mAddedText;
/**
* 常用的邮箱
*/
private HashMap mAutoData = new HashMap();
public AutoCompleteEditText(Context context) {
super(context);
initEmail();
addTextChangedListener(this);
}
public AutoCompleteEditText(Context context, AttributeSet attrs) {
super(context, attrs);
initEmail();
addTextChangedListener(this);
}
public AutoCompleteEditText(Context context, AttributeSet attrs,
int defStyle) {
super(context, attrs, defStyle);
initEmail();
addTextChangedListener(this);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
protected void onFocusChanged(boolean focused, int direction,
Rect previouslyFocusedRect) {
if (!focused) {
append(mAddedText);
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
@Override
public void afterTextChanged(Editable s) {
String text = s.toString();
mFlag = true;
Iterator> iterator = mAutoData.entrySet()
.iterator();
// 遍历常用邮箱
while (iterator.hasNext()) {
Map.Entry entry = iterator.next();
if (text.endsWith(entry.getKey())) {
drawAddedText(entry.getValue());
mAddedText = entry.getValue();
mFlag = false;
break;
}
}
// 如果没有匹配,就画一个空
if (mFlag) {
drawAddedText("");
mAddedText = "";
}
}
/**
* 画出后缀字符串
*
* @param addedText
*/
@SuppressWarnings("deprecation")
private void drawAddedText(String addedText) {
// 如果字符串为空,画空
if (addedText.equals("")) {
setCompoundDrawables(null, null, null, null);
return;
}
// 只需要初始化一次
if (mBitmap == null) {
mHeight = getHeight();
mWidth = getWidth();
// 初始化画笔
mPaint = new Paint();
mPaint.setColor(Color.GRAY);
mPaint.setAntiAlias(true);// 去除锯齿
mPaint.setFilterBitmap(true);// 对位图进行滤波处理
mPaint.setTextSize(getTextSize());
}
// 计算baseLine
Rect rect = new Rect();
int baseLineLocation = getLineBounds(0, rect);
mBaseLine = baseLineLocation - rect.top;
// 添加的字符窜的长度
int addedTextWidth = (int) (mPaint.measureText(addedText) + 1);
// 创建bitmap
mBitmap = Bitmap.createBitmap(addedTextWidth, mHeight,
Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
// 绘制后缀字符串
mCanvas.drawText(addedText, 0, mBaseLine, mPaint);
// bitmap转化为Drawable
mDrawable = new BitmapDrawable(mBitmap);
String text = getText().toString();
// 计算后缀字符串在输入框中的位置
int addedTextLeft = (int) (mPaint.measureText(text) - mWidth + addedTextWidth);
int addedTextRight = addedTextLeft + addedTextWidth;
int addedTextTop = 0;
int addedTextBottom = addedTextTop + mHeight;
// 设置后缀字符串位置
mDrawable.setBounds(addedTextLeft, addedTextTop, addedTextRight,
addedTextBottom);
// 显示后缀字符串
setCompoundDrawables(null, null, mDrawable, null);
}
/**
* 初始化常用的邮箱
*/
private void initEmail() {
mAutoData.put("@q", "q.com");
mAutoData.put("@qq", ".com");
mAutoData.put("@qq.", "com");
mAutoData.put("@qq.c", "om");
mAutoData.put("@qq.co", "m");
mAutoData.put("@1", "63.com");
mAutoData.put("@16", "3.com");
mAutoData.put("@163", ".com");
mAutoData.put("@163.", "com");
mAutoData.put("@163.c", "om");
mAutoData.put("@163.co", "m");
mAutoData.put("@s", "ina.cn");
mAutoData.put("@si", "na.cn");
mAutoData.put("@sin", "a.cn");
mAutoData.put("@sina", ".cn");
mAutoData.put("@sina.", "cn");
mAutoData.put("@sina.c", "n");
mAutoData.put("@s", "ina.com");
mAutoData.put("@si", "na.com");
mAutoData.put("@sin", "a.com");
mAutoData.put("@sina", ".com");
mAutoData.put("@sina.", "com");
mAutoData.put("@sina.c", "om");
mAutoData.put("@sina.co", "m");
mAutoData.put("@1", "26.com");
mAutoData.put("@12", "6.com");
mAutoData.put("@126", ".com");
mAutoData.put("@126.", "com");
mAutoData.put("@126.c", "om");
mAutoData.put("@126.co", "m");
}
}
主类MainActivity.java:
package com.lt.flowlayoutDemo;
import android.app.Activity;
import android.os.Bundle;
import com.lt.flowlayouttest.R;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
布局文件activity_main.xml:
补充:可以在EditText外面加一个RelativeLayout,设置RelativeLayout背景,即可不同样式的EditText。
5.源码下载(有注释)
http://download.csdn.net/detail/a15501628162/8495663
git地址:https://github.com/heheLT/AutoCompleteEditText