Android學(xué)習(xí)筆記3-AutoCompleteTextView

項(xiàng)目需求是用戶登錄界面,輸入email的EditView里,彈出手機(jī)內(nèi)保存的account list,使用戶又可以手動(dòng)輸入,又可以直接從列表里選擇。

首先搜到一個(gè)很棒的實(shí)現(xiàn)方法:帶彈出列表的EditText。這篇博客嘗試了兩種方式實(shí)現(xiàn):ListPopupWindowAutoCompleteTextView。博主先用了后者,說(shuō)特別是在橫屏切換的時(shí)候不方便,最后選擇了前者。自己真實(shí)嘗試了之后,才發(fā)現(xiàn)自己的需求反而是后者=。= (沒(méi)有好好理解博主意思的后果)

小白雖然源碼也讀的不是很明白,但AutoCompleteTextView的大概邏輯是:

watcher監(jiān)控->檢測(cè)到輸入變化->performingFilter從可選列表里過(guò)濾出與輸入匹配的list->彈出listPopupWindow

這樣一看就明白了,autoCompleteTextView比listPopupWindow多了只顯示匹配后的過(guò)程。估計(jì)那位博主沒(méi)有這樣的需求,只需要全部顯示list。而我們這邊的項(xiàng)目畫(huà)面又不需要橫屏,所以我們還是使用AutoCompleteTextView比較方便。
根據(jù)需求我們修改了原生代碼的兩個(gè)功能:

  1. 輸入內(nèi)容為空的時(shí)候也能彈出列表(源碼雖然有可以設(shè)置輸入長(zhǎng)度的threshold,但必須長(zhǎng)度大于0)
    -->在調(diào)用部分增加onFocusChanged處理,且autoCompleteTextView里重載enoughToFilter()保證輸入為空也會(huì)filter更新列表。
  1. 內(nèi)容匹配不止是從頭開(kāi)始匹配,也實(shí)現(xiàn)中間的部分匹配
    -->adapter里重載performingFilter()函數(shù)。匹配函數(shù)從原來(lái)的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函數(shù):

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;
    }
}

實(shí)際調(diào)用代碼片段:

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結(jié)果如下圖(應(yīng)用在項(xiàng)目里依然很完美?。?/p>

autoCompleteTextView實(shí)現(xiàn)

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,217評(píng)論 25 708
  • //Clojure入門(mén)教程: Clojure – Functional Programming for the J...
    葡萄喃喃囈語(yǔ)閱讀 4,055評(píng)論 0 7
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,686評(píng)論 1 51
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,654評(píng)論 19 139
  • 夜已深,但還是不能入眠。在十幾分鐘之前,發(fā)生了一看事情。我正在睡著與未睡著之間進(jìn)行,突然聽(tīng)到了開(kāi)門(mén)的聲音,開(kāi)了一會(huì)...
    心醉布魯斯閱讀 260評(píng)論 0 1

友情鏈接更多精彩內(nèi)容