Android学习系列之控件 AutoCompleteTextView邮箱后缀自动补全

来源:互联网 发布:网线布局知乎 编辑:程序博客网 时间:2024/05/01 20:56

因为项目需要,要写一个邮箱自动补全的自动完成框,如下图:

由于原有的AutoCompleteTextView只是按照相同的字符串匹配,所以这里要自定义AutoCompleteTextView,然后复写里面的一些方法

public class EmailAutoCompleteTextView extends AutoCompleteTextView {    private static final String TAG = "EmailAutoCompleteTextView";    private String[] emailSufixs = new String[]{"@qq.com", "@163.com", "@126.com", "@gmail.com", "@sina.com", "@hotmail.com",            "@yahoo.cn", "@sohu.com", "@foxmail.com", "@139.com", "@yeah.net", "@vip.qq.com", "@vip.sina.com"};    public EmailAutoCompleteTextView(Context context) {        super(context);        init(context);    }    public EmailAutoCompleteTextView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public EmailAutoCompleteTextView(Context context, AttributeSet attrs,                                     int defStyle) {        super(context, attrs, defStyle);        init(context);    }    public void setAdapterString(String[] es) {        if (es != null && es.length > 0)            this.emailSufixs = es;    }    private void init(final Context context) {        //adapter中使用默认的emailSufixs中的数据,可以通过setAdapterString来更改        this.setAdapter(new EmailAutoCompleteAdapter(context, R.layout.register_auto_complete_item, emailSufixs));        //使得在输入1个字符之后便开启自动完成        this.setThreshold(1);        this.setOnFocusChangeListener(new OnFocusChangeListener() {            @Override            public void onFocusChange(View v, boolean hasFocus) {                if (hasFocus) {                    String text = EmailAutoCompleteTextView.this.getText().toString();                    //当该文本域重新获得焦点后,重启自动完成                    if (!"".equals(text))                        performFiltering(text, 0);                } else {                    //当文本域丢失焦点后,检查输入email地址的格式                    EmailAutoCompleteTextView ev = (EmailAutoCompleteTextView) v;                    String text = ev.getText().toString();                    //这里正则写的有点粗暴:)                    if (text != null && text.matches("^[a-zA-Z0-9_]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$")) {                    } else {                        Toast toast = Toast.makeText(context, "邮件地址格式不正确", Toast.LENGTH_SHORT);                        toast.show();                    }                }            }        });    }    @Override    protected void replaceText(CharSequence text) {        //当我们在下拉框中选择一项时,android会默认使用AutoCompleteTextView中Adapter里的文本来填充文本域        //因为这里Adapter中只是存了常用email的后缀        //因此要重新replace逻辑,将用户输入的部分与后缀合并        Log.i(TAG + " replaceText", text.toString());        String t = this.getText().toString();        int index = t.indexOf("@");        if (index != -1)            t = t.substring(0, index);        super.replaceText(t + text);    }    @Override    protected void performFiltering(CharSequence text, int keyCode) {        //该方法会在用户输入文本之后调用,将已输入的文本与adapter中的数据对比,若它匹配        //adapter中数据的前半部分,那么adapter中的这条数据将会在下拉框中出现        Log.i(TAG + " performFiltering", text.toString() + "   " + keyCode);        String t = text.toString();        //因为用户输入邮箱时,都是以字母,数字开始,而我们的adapter中只会提供以类似于"@163.com"        //的邮箱后缀,因此在调用super.performFiltering时,传入的一定是以"@"开头的字符串        int index = t.indexOf("@");        if (index == -1) {            if (t.matches("^[a-zA-Z0-9_]+$")) {                super.performFiltering("@", keyCode);            } else                this.dismissDropDown();//当用户中途输入非法字符时,关闭下拉提示框        } else {            super.performFiltering(t.substring(index), keyCode);        }    }    private class EmailAutoCompleteAdapter extends ArrayAdapter<String> {        public EmailAutoCompleteAdapter(Context context, int textViewResourceId, String[] email_s) {            super(context, textViewResourceId, email_s);        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            Log.i(TAG, "in GetView");            View v = convertView;            if (v == null)                v = LayoutInflater.from(getContext()).inflate(                        R.layout.register_auto_complete_item, null);            TextView tv = (TextView) v.findViewById(R.id.tv);            String t = EmailAutoCompleteTextView.this.getText().toString();            int index = t.indexOf("@");            if (index != -1)                t = t.substring(0, index);            //将用户输入的文本与adapter中的email后缀拼接后,在下拉框中显示            tv.setText(t + getItem(position));            Log.i(TAG, tv.getText().toString());            return v;        }    }}

下拉框的item的xml文件

<?xml version="1.0" encoding="utf-8"?><TextView xmlns:android="http://schemas.android.com/apk/res/android"          android:id="@+id/tv"          android:padding="8dp"          android:layout_width="match_parent"          android:layout_height="wrap_content"/>

现在就可以直接引用了,引用的时候注意自定义文件的路径

<com.example.view.widgets.EmailAutoCompleteTextView            android:id="@+id/act"            android:layout_width="match_parent"            android:layout_height="wrap_content"            android:hint="请输入您常用的邮箱"            android:textColor="@color/black"            android:shadowColor="@color/gray"            android:shadowRadius="1"            android:numeric="decimal"/>

到这里,自定义补全的功能全部实现了,但是有一点是样式的问题,如下图:


系统默认的EditText的边框颜色是橘黄色,但是想改就得自己手动修改了

修改的方法其实很简单,只要在xml文件中应用该自定义框的地方设置background的属性就好了

我设置了白色如第一张图就是没有橘黄色的边框的

谢谢某个大哥(隔了好久也不知道是那一位的了,所以这里没给链接不好意思),我也是看了他写的AutoCompleteTextView,但是在网上搜修改边框,似乎找不到。


4 0
原创粉丝点击