仿知乎登陆邮箱自动补全

项目要求:

登陆界面输入邮箱,自动匹配常用邮箱并自动补全后缀。

比如邮箱为10376129@qq.com,当我输入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<String, String> mAutoData = new HashMap<String, String>();

	/**
	 * 邮箱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<Map.Entry<String, String>> iterator = mAutoData.entrySet()
				.iterator();
		// 遍历常用邮箱
		while (iterator.hasNext()) {
			Map.Entry<String, String> 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<String, String> mAutoData = new HashMap<String, String>();

	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<Map.Entry<String, String>> iterator = mAutoData.entrySet()
				.iterator();
		// 遍历常用邮箱
		while (iterator.hasNext()) {
			Map.Entry<String, String> 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:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="${relativePackage}.${activityClass}" >

    <com.lt.flowlayoutDemo.AutoCompleteEditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@null"
        android:textSize="20sp"
        android:singleLine="true" />

</LinearLayout>


补充:可以在EditText外面加一个RelativeLayout,设置RelativeLayout背景,即可不同样式的EditText。


5.源码下载(有注释)

http://download.csdn.net/detail/a15501628162/8495663

git地址:https://github.com/heheLT/AutoCompleteEditText






  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值