android文本框联想AppCompatAutoCompleteTextView

官方文档
根据输入自动联想内容

基本使用

activity_main.xml

1
2
3
4
5
<android.support.v7.widget.AppCompatAutoCompleteTextView
android:id="@+id/trainId"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

其他的一些属性

属性 描述
android:completionHint 设置出现在下拉菜单底部的提示信息
android:completionThreshold 设置触发补全提示信息的字符个数
android:dropDownHorizontalOffset 设置下拉菜单于文本框之间的水平偏移量
android:dropDownHeight 设置下拉菜单的高度
android:dropDownWidth 设置下拉菜单的宽度
android:singleLine 设置单行显示文本内容
android:dropDownVerticalOffset 设置下拉菜单于文本框之间的垂直偏移量

java中的调用
MainActivity.java

1
2
3
4
5
6
7
AppCompatAutoCompleteTextView autoCompleteTextView = (AppCompatAutoCompleteTextView) findViewById(R.id.trainId);
String[] mSearchHistoryArray = new String[]{"111", "222", "12"};
ArrayAdapter mSearchAdapter = new ArrayAdapter<String>(
context,
android.R.layout.simple_dropdown_item_1line,
mSearchHistoryArray);
autoCompleteTextView.setAdapter(mSearchAdapter);

自定义AdApter

自定义效果

其实这个自定义和自定义listview很像,重写baseAdapter,实现Filterable(过滤器接口)

  • 先写出来布局

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="8dp"
    android:text="TextView"
    app:layout_constraintStart_toStartOf="parent"/>

    <ImageView
    android:id="@+id/imageView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    android:src="@android:drawable/ic_delete"/>
    </android.support.constraint.ConstraintLayout>
  • 适配器

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    public class AutoCompleteAdapter extends BaseAdapter implements Filterable {
    private static final String TAG = "AutoCompleteAdapterr";
    private String[] emails = {"@qq.com","@163.com","@sina.com","@gmail.com"};
    private Context context;
    public AutoCompleteAdapter(Context context){
    this.context = context;
    }
    private ArrayList<String> data = new ArrayList<>();
    @Override
    public int getCount() {
    return data.size();
    }
    @Override
    public Object getItem(int position) {
    return data.get(position);
    }
    @Override
    public long getItemId(int position) {
    return position;
    }
    private class ViewHolder{
    TextView textView;
    ImageView imageView;
    }
    @Override
    public View getView(final int position, View convertView, ViewGroup parent) {
    ViewHolder viewHolder;
    if(convertView==null){
    convertView = LayoutInflater.from(context).inflate(R.layout.auto_complete_layout,parent,false);
    viewHolder = new ViewHolder();
    viewHolder.textView = (TextView)convertView.findViewById(R.id.textView);
    viewHolder.imageView = (ImageView)convertView.findViewById(R.id.imageView);
    convertView.setTag(viewHolder);
    }else{
    viewHolder = (ViewHolder)convertView.getTag();
    }
    viewHolder.textView.setText(data.get(position));
    viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    data.remove(position);
    notifyDataSetChanged();
    }
    });
    return convertView;
    }
    @Override
    public Filter getFilter() {
    return new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
    Log.d(TAG, "performFiltering: "+constraint);
    FilterResults results = new FilterResults();
    ArrayList<String> newData = new ArrayList<>();
    if(constraint != null && !constraint.toString().contains("@")){
    for(String data : emails){
    newData.add(constraint+data);
    }
    }
    results.values = newData;
    results.count = newData.size();
    return results;
    }

    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
    data = (ArrayList)results.values;
    notifyDataSetChanged();
    }
    };
    }
    }
  • BaseAdapter是一个普通的适配器,用了一个列表优化

  • 重写的Filter实现了一个getFilter方法
  • Filter要实现两个抽象方法
    performFiltering是传入一个字符串,是用户在文本框中输入的字符串,要返回一个FilterResults记录返回的数据,values记录数据值,count记录数据的长度,上面的代码是把输入的字符串加上邮箱后缀组成一个列表
    这个值返回以后会传到publishResults方法,这个方法就是处理这个上面传过来的FilterResults,上面代码是把传入的数组赋值给data,然后调用notifyDataSetChanged方法更新列表