从名称上可看出来,这两个控件都是用于输入信息的TextView,AutoComplete已表明这两个控件内容输入都是自动完成的。区别在于一个是Multi,允许在一个编辑框里输入多个自动完成的字符串,比如输入多个标签;另一个不是Multi,一个编辑框只允许一个字符串自动完成,比如邮箱地址的补全。具体的区别可通过下面的内容看出来。下面分别介绍着两个控件的使用。


AutoCompleteTextView

功能

动态匹配输入的内容,如搜索引擎在输入框输入信息时,会有一个下拉列表显示与当前输入内容有关的信息。

控件特有属性

如同width、height等属性是控件共有属性,下面介绍AutoCompleteTextView特有的属性:

  • android:completionThreshold : 此属性用于设置当输入多少字符时控件开始进行自动匹配
  • android:completionHint : 设置出现在下拉菜单中的提示标题
  • android:dropDownHorizontalOffset : 下拉菜单于文本框之间的水平偏移。默认与文本框左对齐
  • android:dropDownHeight : 下拉菜单的高度
  • android:dropDownWidth : 下拉菜单的宽度
  • android:singleLine : 单行显示
  • android:dropDownVerticalOffset : 垂直偏移量

如下,设置控件在输入1个字符后就开始自动匹配

<AutoCompleteTextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"
        android:completionThreshold="1" />

控件在Activity中的使用

AutoCompleteTextView在Activity中的使用分为三步:

  1. 实例化控件,即通过findViewById找到控件
  2. 准备数据源,数据源里的数据将与输入内容进行匹配,匹配的就显示在下拉列表里
  3. 设置适配器,这一步与ListView等控件一样,我们需要适配器将数据域与界面连接起来

下面是一个实例:
1.创建工程

2.修改 actiivty_main 如下:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.twotextview.MainActivity" >

    <AutoCompleteTextView
        android:id="@+id/tv_auto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:completionThreshold="1" />

</RelativeLayout>

3.MainActivity中代码:

package com.twotextview;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;

public class MainActivity extends ActionBarActivity {

 private AutoCompleteTextView autoCompleteTextView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 1. 实例化控件
        this.autoCompleteTextView = (AutoCompleteTextView) findViewById(R.id.tv_auto);
       
        // 2. 准备数据源,即下拉列表中显示的数据
        String[] datas = new String[]{
         "Hello",
         "Hay",
         "Ha",
         "World",
         "Word",
         "Wa!"
        };
       
        // 3. 设置适配器,为控件填充数据
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
          android.R.layout.simple_list_item_1,datas);
        this.autoCompleteTextView.setAdapter(adapter);
       
    }

}

4.运行结果如下:
这里写图片描述

因为我们只是做一个简单的Demo,所以在适配器的选择上,选择了最简单的ArrayAdapter,如果要显示图文结合的,可以使用BaseAdapter或SimpleAdapter。


MultiAutoCompleteTextView

功能

可支持用分隔符分开来选择多个值,比如在发送邮件时的选择联系人、个性化设置里选择个人标签等。
在输入第一个值时,它能自动匹配,选择完后,输入分隔符,在输入内容时,它又可以自动匹配。

实现步骤

  1. 实例化控件,即通过findViewById找到控件
  2. 准备数据源,数据源里的数据将与输入内容进行匹配,匹配的就显示在下拉列表里
  3. 设置适配器,这一步与ListView等控件一样,我们需要适配器将数据域与界面连接起来
  4. 设置分隔符,可以自己创建分隔符Tokenizer,也可以使用内部的默认以英文逗号为分隔符的Tokenizer

下面是实例:
1.创建工程(也可以在上一个工程的基础上修改)

2.修改 activity_main 文件:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.twotextview.MainActivity" >

    <MultiAutoCompleteTextView
        android:id="@+id/tv_multiAuto"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text=""
        android:completionThreshold="1" 
       	/>

</RelativeLayout>

3.修改MainActivity:

package com.twotextview;

import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.MultiAutoCompleteTextView;

public class MainActivity extends ActionBarActivity {
 
 private MultiAutoCompleteTextView multiAutoCompleteTextView;
 
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 1. 实例化控件
        this.multiAutoCompleteTextView = (MultiAutoCompleteTextView) findViewById(R.id.tv_multiAuto);
       
        // 2. 准备数据源,即下拉列表中显示的数据
        String[] datas = new String[]{
         "Hello",
         "Hay",
         "Ha",
         "World",
         "Word",
         "Wa!"
        };
       
        // 3. 设置适配器,为控件填充数据
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
          android.R.layout.simple_list_item_1,datas);
        this.multiAutoCompleteTextView.setAdapter(adapter);
       
        // 4. 设置分隔符
        this.multiAutoCompleteTextView.setTokenizer(
          new MultiAutoCompleteTextView.CommaTokenizer());
    }
    
}

其中与AutoCompleteTextView有所区别也只有设置分隔符这一步;

4.运行结果:
这里写图片描述

在输入了三条内容后,在输入逗号分隔符后,又可以开始自动匹配。


注:如果要使用自己自定义的分隔符,需要写一个类继承Tokenizer接口,然后实现里面的方法。这里可以先查看MultiAutoCompleteTextView.CommaTokenizer()的源码,然后再自己实现。附录一下源码:

/**
     * This simple Tokenizer can be used for lists where the items are
     * separated by a comma and one or more spaces.
     */
    public static class CommaTokenizer implements Tokenizer {
        public int findTokenStart(CharSequence text, int cursor) {
            int i = cursor;

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

            return i;
        }

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

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

            return len;
        }

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

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

            if (i > 0 && text.charAt(i - 1) == ',') {
 
                return text;
            } else {
                if (text instanceof Spanned) {
                    SpannableString sp = new SpannableString(text + ", ");
                    TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
                                            Object.class, sp, 0);
                    return sp;
                } else {
                    return text + ", ";
                }
            }
        }
    }