顯示具有 Filter 標籤的文章。 顯示所有文章
顯示具有 Filter 標籤的文章。 顯示所有文章

2008年12月15日 星期一

如何在 ListView 上加上按鍵過濾的功能

How to add type filter functionality for your ListView widgets?

由於手機螢幕的大小有限,為了要顯示更多的資料,ListView 通常是首選元件。因此,在各式的應用程式中,幾乎都可以見到他的身影。ListView 不只好用,ListView 也提供了各式各樣的客製化功能。我想,他可算是 Android 中,功能最為複雜的元件之一。

今天要分享給大家的,就是如何在 ListView 中 加上按鍵過濾的功能。

想要知道什麼是『按鍵過濾』?想想,當你有上百個聯絡人時,如何快速地找到一個叫 Sam 的人?要知道答案,執行 Contacts 這個程式,按下 's' 鍵,這時你會發現只剩 s 開頭的聯絡人,再按下 a 鍵,幾乎答案就呼之欲出了,因為以 sa 開頭的聯絡人,只剩屈指可數的數目。這種依照你按鍵輸入的文字,來過濾 ListView 所要顯示的內容,就是我這提的『按鍵過濾』功能。

要如何做到這功能?為了要找到解法,我開始翻出 Contacts 的原始碼,仔細研究他是如何做到的。在研讀原始碼的過程中,還意外發現其中還藏了 Android Secret Code 這個東西。試試,在你的 G1 手機上,輸入 *#*#4636#*#* 。嘿嘿,你看到什麼了嗎?用模擬器,是沒用的,一定要實體手機才行。還有更多的 secret code ,我貼在 Android secret code 這篇文章上。有興趣的,自己上去瞧瞧。

好了,言歸正傳。關於要如何做到『按鍵過濾』功能的答案,其實非常簡單,就是對你的 ListView 加上 setTextFilterEnabled(true) ,就可以了。

對你的程式沒效嗎?先別急,這還有個但書,那就是你透過 ListView.setAdapter() 所傳入的 ListAdapter, 一定要實現 Filterable 這個介面才行。目前,ArrayAdapter,CursorAdapter 和 SimpleAdapter 這幾個 Adapter 都有實現 Filterable 這個介面。一般大家常用的是 ArrayAdapter<String> ,那你只要對你的 ListView 加上 setTextFilterEnabled(true) ,應該馬上就有『按鍵過濾』的功能。在 API Demos 程式中,第一個畫面內的 ListView 也有加上這功能。

不過,通常事情都沒這麼簡單。像我的 ListAdapter 就是繼承自 BaseAdapter,做出自己的 Adapter。BaseAdapter 當然沒有實現 Filterable 這個介面。你得自行實現 Filterable 介面所要求的 performFiltering() 和 publishResults() 函式。

如何實現這兩個函式?我在 在 Android 上利用 Google APIs 實現 Google Suggestion 功能 這篇文章中,有提到過。

另外,別忘了,你還有 Android 原始碼可以參考,那是你最好的導師。為了幫助你的了解,我將 platform\framework\base\core\java\android\widget\ArrayAdapter.java 原始碼中,關於如何實現 Filterable 介面的部份,貼出來,分享給你。


繼續閱讀全文...

2008年7月7日 星期一

客製化 AutoCompleteTextView 中的 Filter 功能

How to customize the filtering function for AutoCompleteTextView widget?

這裡 我提過,另一個縮小 AutoCompleteTextView 的方法,就是自己寫個 ArrayAdapter,然後在 getView() 中,產生個 TextView 給 AutoCompleteTextView。這簡單的程式片段,大致如下。在 getView() 函式中,自己 new 個 TextView widget。

不過,要寫個可以給 AutoCompleteTextView 用的 ArrayAdapter,可沒表面上看起來那麼地簡單。因為,你還要在這個類別裡,寫個 Filterable 介面的實現才行。

這個 Filterable interface 就是用來,從現有的全部結果中,依照你輸入的字元,過濾出符合的結果。而 AutoCompleteTextView ,則只單純地列出 Filterable 所傳回的結果。例如,當你輸入個 B 字元時,AutoCompleteTextView 就藉由 Filterable 的函式,列出只有 B 開頭的國家。這也是 AutoCompleteTextView 中,最主要的功能。

不過,如果你想要列出所有的國家,AutoCompleteTextView 目前可沒這樣的功能。最簡單的方式,就是自己寫個 Filterable 的實現。所以啦,Filterable 可不是只能用來過濾結果。你可拿它來做任何事,AutoCompleteTextView 根本不管他傳回的內容是什麼,他只單純地列出 Filterable 所傳回的結果。

延續 這裡 的例子,我將他改成,如果只輸入 "*" 這個字元,就列出所有的國家。如果是其他字元,就依照原先的用法,列出符合輸入字元的國家。

在 Filterable 這個介面中,你要實現這兩個方法。

底下就是,如何在這兩個函式中,實現用 "*" 列出所有國家。

還沒完,接下來,你還要在你自己的 ArrayAdapter (這裡的 CntyListAdapter),實現下列的方法才行。

好了,最後的執行結果就像這樣。你想到要利用 Filterable ,來做出什麼特別功能嗎?


繼續閱讀全文...