美文网首页安卓基础知识Android知识Android开发
Android学习笔记3-AutoCompleteTextVie

Android学习笔记3-AutoCompleteTextVie

作者: Isabella_Bing | 来源:发表于2016-09-02 10:15 被阅读731次

    项目需求是用户登录界面,输入email的EditView里,弹出手机内保存的account list,使用户又可以手动输入,又可以直接从列表里选择。

    首先搜到一个很棒的实现方法:带弹出列表的EditText。这篇博客尝试了两种方式实现:ListPopupWindowAutoCompleteTextView。博主先用了后者,说特别是在横屏切换的时候不方便,最后选择了前者。自己真实尝试了之后,才发现自己的需求反而是后者=。= (没有好好理解博主意思的后果)

    小白虽然源码也读的不是很明白,但AutoCompleteTextView的大概逻辑是:

    watcher监控->检测到输入变化->performingFilter从可选列表里过滤出与输入匹配的list->弹出listPopupWindow

    这样一看就明白了,autoCompleteTextView比listPopupWindow多了只显示匹配后的过程。估计那位博主没有这样的需求,只需要全部显示list。而我们这边的项目画面又不需要横屏,所以我们还是使用AutoCompleteTextView比较方便。
    根据需求我们修改了原生代码的两个功能:

    1. 输入内容为空的时候也能弹出列表(源码虽然有可以设置输入长度的threshold,但必须长度大于0)
      -->在调用部分增加onFocusChanged处理,且autoCompleteTextView里重载enoughToFilter()保证输入为空也会filter更新列表。
    1. 内容匹配不止是从头开始匹配,也实现中间的部分匹配
      -->adapter里重载performingFilter()函数。匹配函数从原来的startwith(...)修改为contains(...)即可

    重载AutoCompleteTextView:

    public class InstantAutoCompleteTextView extends AutoCompleteTextView {
    
        public InstantAutoCompleteTextView(Context context) {
            super( context );
        }
    
        public InstantAutoCompleteTextView(Context context, AttributeSet attrs) {
            super( context, attrs );
        }
    
        public InstantAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
            super( context, attrs, defStyle );
        }
    
        @Override
        protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
            super.onFocusChanged(focused, direction, previouslyFocusedRect);
            if (focused && getAdapter() != null) {
                performFiltering(getText(), KeyEvent.KEYCODE_UNKNOWN);
            }
        }
    
        @Override
        public boolean enoughToFilter() {
            return true;
        }
    
    }
    

    重载adapter部分,自定义performingFilter函数:

    public class AutoCompleteAdapter<T> extends ArrayAdapter<T> implements Filterable {
        private List<T> listObjects;
        List<T> suggestions = new ArrayList<>();
    
        private Filter mFilter = new Filter(){
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults filterResults = new FilterResults();
    
                if(constraint != null) {
                    suggestions.clear();
                    for(T object : listObjects){
                        if(object.toString().toLowerCase().contains(constraint.toString().toLowerCase())){
                            suggestions.add(object);
                        }
                    }
    
                    filterResults.values = suggestions;
                    filterResults.count = suggestions.size();
                }
    
                return filterResults;
            }
    
            @SuppressWarnings( "unchecked" )
            @Override
            protected void publishResults(CharSequence contraint, FilterResults results) {
                if(results == null){
                    notifyDataSetInvalidated();
                    return;
                }
    
                List<T> filteredList = (List<T>) results.values;
                if(results.count > 0) {
                    clear();
                    for (T filteredObject : filteredList) {
                        add(filteredObject);
                    }
                    notifyDataSetChanged();
                }
            }
        };
    
        public AutoCompleteAdapter(Context context, int resource, List<T> listObjects) {
            super(context, resource, listObjects);
            this.listObjects =new ArrayList<>( listObjects );
        }
    
        @Override
        public Filter getFilter() {
            return mFilter;
        }
    }
    

    实际调用代码片段:

    public class MainActivity extends AppCompatActivity {
    
        private InstantAutoCompleteTextView autoTextView;
        private ArrayList<String> listArray;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initialize();
    
        }
    
        private void initialize(){
            listArray=new ArrayList<>();
            listArray.add("test 1");
            listArray.add("test 2");
            listArray.add("test 3");
            listArray.add("default 9");
            listArray.add("beautiful");
            listArray.add("hello world");
            listArray.add("boring sunday");
            listArray.add("list test");
            autoTextView=(InstantAutoCompleteTextView) findViewById(R.id.autoCompleteText);
    
            AutoCompleteAdapter autocompleteAdapter = new AutoCompleteAdapter(this,android.R.layout.simple_list_item_1,listArray);
            autoTextView.setAdapter(autocompleteAdapter);
        }
    }
    

    最后test结果如下图(应用在项目里依然很完美!):


    autoCompleteTextView实现

    p.s. test的代码:
    https://github.com/bingningO/AutoCompleteTextViewTest

    相关文章

      网友评论

      • 价值创造营:博主,源码是否能分享下?
        Isabella_Bing:@L_RollBack 抱歉拖了很久,test代码链接放在文章最后了哦~

      本文标题:Android学习笔记3-AutoCompleteTextVie

      本文链接:https://www.haomeiwen.com/subject/bqmhettx.html