一手遮天 Android - view(文本类): AutoCompleteTextView 基础

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

一手遮天 Android - view(文本类): AutoCompleteTextView 基础

示例如下:

/view/text/AutoCompleteTextViewDemo1.java

/**
 * AutoCompleteTextView - 自动完成文本框
 *
 * 本例演示
 * 1、如何通过 ArrayAdapter 绑定数据和模板
 * 2、如何通过自定义的 BaseAdapter 并实现 Filterable 接口来绑定数据和模板
 * 3、如何监听下拉列表的点击事件,并获取选中项的数据对象
 */

package com.webabcd.androiddemo.view.text;

import android.content.Context;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;

import com.webabcd.androiddemo.R;

import java.util.ArrayList;
import java.util.List;

public class AutoCompleteTextViewDemo1 extends AppCompatActivity {

    private AutoCompleteTextView mAutoCompleteTextView1;
    private AutoCompleteTextView mAutoCompleteTextView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_text_autocompletetextviewdemo1);

        mAutoCompleteTextView1 = findViewById(R.id.autoCompleteTextView1);
        mAutoCompleteTextView2 = findViewById(R.id.autoCompleteTextView2);

        sample1();
        sample2();
    }

    // 通过 ArrayAdapter 绑定数据和模板
    private void sample1() {
        String[] data = new String[]{"abc", "abcd", "abcde", "abcdef", "abcdefg"};
        mAutoCompleteTextView1.setAdapter(new ArrayAdapter<String>(AutoCompleteTextViewDemo1.this, android.R.layout.simple_dropdown_item_1line, data));
    }

    // 通过自定义的 BaseAdapter 并实现 Filterable 接口来绑定数据和模板
    private void sample2() {
        // 构造数据
        final List<MyData> myDataList = new ArrayList<MyData>();
        myDataList.add(new MyData("abc", "abc"));
        myDataList.add(new MyData("abcd", "abcd"));
        myDataList.add(new MyData("abcde", "abcde"));
        myDataList.add(new MyData("abcdef", "abcdef"));
        myDataList.add(new MyData("abcdefg", "abcdefg"));

        // 实例化自定义的 BaseAdapter(注:为 AutoCompleteTextView 提供数据必须要实现 Filterable 接口)
        final MyAdapter myAdapter = new MyAdapter(myDataList, this);
        mAutoCompleteTextView2.setAdapter(myAdapter);

        // 点击了下拉列表中的某一项时的事件
        mAutoCompleteTextView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // 下面这个获取的不是选中项的对象
                // MyData myData = myDataList.get(position);

                // 下面这个获取的才是选中项的对象
                MyData myData = (MyData) parent.getItemAtPosition(position);
            }
        });
    }

// 自定义实体类
class MyData {
    private String _name;
    private String _comment;

    public MyData() {
    }

    public MyData( String name, String comment) {
        this._name = name;
        this._comment = comment;
    }

    public String getName() {
        return _name;
    }

    public String getComment() {
        return _comment;
    }

    public void setName(String name) {
        this._name = name;
    }

    public void setComment(String comment) {
        this._comment = comment;
    }

    // 选中下拉列表的某一项后,将调用此项对应的对象的 toString() 方法,并将其结果赋值给 AutoCompleteTextView 文本框
    // 所以如果绑定的数据是自定义对象的话,要重写其 toString() 方法,以便在 AutoCompleteTextView 的文本框中显示合适的值
    @Override
    public String toString() {
        return _name;
    }
}

// 自定义 BaseAdapter,并实现 Filterable 接口(注:绑定到 AutoCompleteTextView 时,必须要实现 Filterable 接口)
class MyAdapter extends BaseAdapter implements Filterable {

    private List<MyData> _myDataListOriginal; // 原始数据
    private List<MyData> _myDataListFiltered; // 筛选后的数据(下拉列表需要显示的数据)

    private Context _context;

    public MyAdapter(List<MyData> myDataList, Context context) {
        this._myDataListFiltered = new ArrayList<MyData>();
        this._myDataListOriginal = myDataList;
        this._context = context;
    }

    @Override
    public int getCount() {
        return _myDataListFiltered.size();
    }

    @Override
    public Object getItem(int position) {
        return _myDataListFiltered.get(position);
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if (convertView == null) {
            convertView = LayoutInflater.from(_context).inflate(R.layout.item_view_text_autocompletetextviewdemo1, parent, false);

            holder = new ViewHolder();
            holder.txtName = (TextView) convertView.findViewById(R.id.txtName);
            holder.txtComment = (TextView) convertView.findViewById(R.id.txtComment);
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }

        holder.txtName.setText(_myDataListFiltered.get(position).getName());
        holder.txtComment.setText(_myDataListFiltered.get(position).getComment());

        return convertView;
    }

    // 实现 Filterable 接口
    @Override
    public Filter getFilter() {
        Filter filter = new Filter() {
            /**
             * 删选出符合条件的数据的集合
             * @param constraint 用户输入的数据
             */
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                List<MyData> list = new ArrayList<>();
                if(constraint != null){
                    for (MyData myData : _myDataListOriginal) {
                        if (myData.getName().contains(constraint)) {
                            list.add(myData);
                        }
                    }
                }

                // 符合条件的数据的数量
                results.count = list.size();
                // 符合条件的数据的集合
                results.values = list;

                return results;
            }

            /**
             * 筛选逻辑执行完毕
             * @param constraint 用户输入的数据
             * @param results 由 performFiltering() 返回的筛选结果
             */
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                // 更新下拉框需要显示的数据
                _myDataListFiltered = (List<MyData>) results.values;
                // 刷新下拉框
                notifyDataSetChanged();
            }
        };

        return filter;
    }

    class ViewHolder {
        TextView txtName;
        TextView txtComment;
    }
}
}

/layout/activity_view_text_autocompletetextviewdemo1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <!--
        completionHint/completionHintView - 下拉列表中的提示标题
        completionThreshold - 指定至少输入多少字符后才会弹出下拉列表(默认值为 2)
        dropDownWidth/dropDownHeight - 下拉列表的宽度和高度
        dropDownHorizontalOffset/dropDownVerticalOffset - 下拉列表的水平偏移和垂直偏移
        dropDownAnchor - 下拉列表显示位置关联的组件(默认是自己,也可以通过 @id/xxx 来指定)
        dropDownSelector - 下拉列表中的某一项被点击后的背景
    -->
    <AutoCompleteTextView
        android:id="@+id/autoCompleteTextView1"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:completionHint="建议列表"
        android:completionThreshold="2"
        android:dropDownSelector="@color/red" />

    <AutoCompleteTextView
        android:id="@+id/autoCompleteTextView2"
        android:layout_width="match_parent"
        android:layout_height="48dp"
        android:completionHint="建议列表"
        android:completionThreshold="1"
        android:dropDownSelector="@color/orange" />

</LinearLayout>

/layout/item_view_text_autocompletetextviewdemo1.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/txtName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#1D1D1D"
        android:textSize="24sp" />

    <TextView
        android:id="@+id/txtComment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#B4B4B4"
        android:textSize="14sp" />

</LinearLayout>

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

posted @ 2021-05-31 12:28  webabcd  阅读(73)  评论(0编辑  收藏  举报