2014-08-27 95 views
0

我有一個簡單的問題:列表視圖自動完成

我有一個ListView數據與這些字符串:

String words[] = { 
     "man", 
     "guy", 
     "penny-wise", 
     "(just)", 

我增加了一個搜索funciontality到列表視圖,就像這樣:

  * Enabling Search Filter 
    * */ 
    search.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) { 
      // When user changed the Text 
      Words.this.adapter.getFilter().filter(cs); { 

       lv.setOnItemClickListener(new OnItemClickListener(){ 

        public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, 
        long arg3) { 




        } 

       }); 

      } 


     } 

     @Override 
     public void beforeTextChanged(CharSequence arg0, int arg1, int arg2, 
       int arg3) { 
      // TODO Auto-generated method stub 

     } 

     @Override 
     public void afterTextChanged(Editable arg0) { 
      // TODO Auto-generated method stub       
     } 




    }); 
} 

所以,搜索功能運作良好,但是我希望能夠識別出當我從字符串(列表視圖數據)中輸入角色的一部分作爲明智的項目中的「明智」時,他們不會提供便士作爲建議它應該是(因爲它是在列表視圖數據存在)

如果我只輸入他們不提供的建議...因爲有()在我的字符串...

哪有我解決此問題。我是新手。謝謝!!!

+0

那麼你的'搜索'的東西是一個AutoCompleteTextView? – reVerse 2014-08-27 15:13:12

回答

2

您需要爲適配器創建您自己的自定義過濾器。爲了做到這一點,您需要創建自己的自定義適配器類。這不是一件容易的事,尤其是考慮到你是一個新手。

您沒有提及您使用的是哪種類型的適配器。如果它是一個ArrayAdapter,那麼最好的和最簡單的解決方案就是使用開放源碼庫Advanced-Adapters。它有一個等效的適配器,可以輕鬆地讓您自定義過濾邏輯,但是您需要手動處理視圖創建。你可以閱讀更多關於here

否則,很多人會告訴你直接擴展ArrayAdapter類並覆蓋getFilter()方法,但這是不正確的答案。爲什麼?多種原因。

過濾操作發生在後臺線程上。這意味着你需要擔心併發問題。這提出了一些問題。首先,ArrayAdapter使用的鎖沒有公開,也沒有使用類實例的鎖。這意味着你需要你自己的鎖,這會大大增加死鎖的風險......對同一組數據有兩個不同的鎖是很糟糕的,特別是因爲ArrayAdapter在更多地方同步,然後只是過濾器。

ArrayAdapter使用兩個列表來跟蹤它的數據:mObjects和。前者跟蹤顯示的列表,後者跟蹤整個列表以查看過濾器操作發生的時間。例如,如果過濾10個項目的列表以僅顯示1,那麼適配器在內部仍然需要知道最初的10個用於稍後恢復列表的內容。當覆蓋getFilter()時,您必須提供類似的行爲,但有一個主要問題。 ArrayAdapter不公開任何列表。雖然您可以一次從mObjects中提取項目,但無法拉取整個列表本身。一個常見的解決方案是在用項目實例化自定義適配器時創建另一個列表。

但是,由於在適配器中添加/刪除/更新項目的方式多種多樣,因此會出現更多問題。這意味着您需要重寫每個mutate方法以確保您的列表與ArrayAdapter保持同步。添加一個事實,即您必須考慮適配器是否進一步被過濾會使事情複雜化。基本上你的列表可以很容易地從內部的ArrayAdapter中失去同步。

到此爲止,您已經覆蓋了很多ArrayAdapter的方法,它使得ArrayAdapter在很大程度上無關緊要。在開始跟蹤派生自ArrayAdapter的自定義類中的數據列表的那一刻,您應該停下來並從頭開始實施自己的適配器。

這就是爲什麼從BaseAdapter創建您自己的適配器是最好的解決方案。如果你知道自己在做什麼,那麼做起來並不難......真的很痛苦。否則,該開放源代碼庫將爲您完成所有這些工作,同時保留getView()方法摘要並提供一種自定義過濾器邏輯的方法。

+0

你介意告訴我們爲什麼重寫'getFilter()'方法會是一個不正確的答案? – reVerse 2014-08-27 15:36:46

+0

更新答案與原因。 – 2014-08-27 17:31:50

+0

感謝您的詳細解釋,但我不得不承認,我從來沒有遇到過使用'getFilter()'方法的問題。 (好吧,我幾乎做了你剛剛說的所有事情,即創建第二個列表,處理併發性等等) – reVerse 2014-08-27 17:51:48