安卓不可缺少的自动填充EditText。

来源:互联网 发布:c语言有什么用途 编辑:程序博客网 时间:2024/05/19 22:24

项目中或多或少都要用到输入框。而对于输入框来说,用户想要的最好的体验莫过于输入部分文字后即可选择自动填充。
但是问题来了,安卓中给用户提供的控件AutoCompleteTextView或者MultiAutoCompleteTextView并不能很方便的进行模糊查询。必须要在首字符满足的情况下才能出现结果,而且想自定义也很麻烦。我看了半天的源码,也没有更改好自己想要实现的模糊查询。
所以我就想到使用PopWindow+ListView的方式制造自定义的
自动填充文本框,即AutoText;

先上效果图

输入文字
这里写图片描述

选择相应的item
这里写图片描述

不同效果的短信的模糊搜索
这里写图片描述

这里写图片描述

接下来看代码:

MyAutoText.java
进行数据初始化和查询等操作

/** * Created by 实现自动填充的EditText */public class MyAutoText implements DeliverData{    //保存查询到的数据    private ArrayList<String> myList = new ArrayList<>();           //获取用户提供的list数据      private ArrayList<String> list;      //获取输入框EditText                               private EditText editText;    //获取Activity(因为window必须依赖于Activity)    private Activity activity;    //listview的适配器    private ListViewAdapter adapter;    //显示查询数据的listview    private ListView listView;    //popwindow    private PopupWindow popupWindow;    public MyAutoText(Activity activity, EditText editText, ArrayList<String> list) {        this.activity = activity;        this.editText = editText;        this.list = list;        initdata();    }    //数据初始化    private void initdata(){        adapter = new ListViewAdapter(activity,this);        setPopWindow();        setListener();    }    //为edidtetx添加字符变化的监听事件    private void setListener() {        editText.addTextChangedListener(new TextWatcher() {            @Override            public void beforeTextChanged(CharSequence s, int start, int count, int after) {            }            @Override            public void onTextChanged(CharSequence s, int start, int before, int count) {                 //每次查询前清除上一次查询内容                if (myList != null) {                    myList.clear();                }                //对字符长度进行检索                if(s.length()>0){                    search(String.valueOf(s));                }else{                    adapter.setData(null,null);                }            }            @Override            public void afterTextChanged(Editable s) {            }        });    }    //对用户传递的list进行查询操作    private void search(String s) {        for (String str : list) {            if (str.contains(s)) {                myList.add(str);            }        }        //刷新adapter        adapter.setData(myList, s);        //显示popwindow        popupWindow.showAsDropDown(editText);    }    //设置popwindow    private void setPopWindow() {        LayoutInflater inflater = LayoutInflater.from(activity);        LinearLayout root = (LinearLayout) inflater.inflate(R.layout.autotext_popwindow, null);        listView = (ListView) root.findViewById(R.id.autotext_popwindow_listview);        listView.setAdapter(adapter);        popupWindow = new PopupWindow();        popupWindow.setWidth(editText.getWidth());        popupWindow.setHeight(200);        popupWindow.setContentView(root);    }    //接口回调,获取listview点击事件后给EditText传值    @Override    public void deliverData(String data) {        editText.setText(data);        popupWindow.dismiss();    }}

ListViewAdapter
这里没有什么难处,唯一就是需要接口回调数据

/** *  适配器 */public class ListViewAdapter extends BaseAdapter{    private ArrayList<String> list=new ArrayList<>();    private Activity activity;    private String str;         //查询的关键字    private DeliverData deliverData;    public ListViewAdapter(Activity activity,DeliverData deliverData) {        this.activity=activity;        this.deliverData=deliverData;    }    @Override    public int getCount() {        if(list!=null){            return list.size();        }else{            return 0;        }    }    @Override    public Object getItem(int position) {        return list.get(position);    }    @Override    public long getItemId(int position) {        return 0;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        TextView text=new TextView(activity);        text.setTextSize(18);        text.setText(list.get(position)+"");        text.setId(position);        text.setOnClickListener(new View.OnClickListener() {            @Override            public void onClick(View v) {                //给AutoText回调选中的数据                deliverData.deliverData(list.get(v.getId()));            }        });        return text;    }    //刷新adapter数据    public void setData(ArrayList<String> list,String search){        this.list=list;        this.str=search;        this.notifyDataSetChanged();    }}

DeliverData
创建一个接口,进行数据转发

/** * Created by 转发的数据 */public interface DeliverData {    void deliverData(String data);}

总结:
这种方式实现起来其实很简单。它最大的好处是模糊查询,你可以自定义自己要搜索的形式。你可以选择单一的号码。也可以选择展示带有描述的图片等等。而我觉得有一点瑕疵就是我:
没有自定义用户查询的关键字样式。style。如果说有需要的话可以自己自定义一下。

//然后这里解释一下我遇到的popwindow问题:

popwindow可能在Activity未创建完成的时候就加载。这时候可能会报一个
unable to add the window 的错误信息。
如果出现。用一个线程延迟加载就行了。

0 0