使用者在EinkBro 中輸入網址時,目前有支援即時去搜尋輸入的文字片段是不是有符合的書籤名稱/網址,或是瀏覽過的標題/網址。這功能是利用原生 Android 的 AutoCompleteTextView
,但是在 Compose 世界裡還有沒內建這元件。目前雖然 AutoCompleteTextView
大致符合需求,但有一個小小的行為我一直很想改掉:
當使用者點擊輸入框,輸入框取得焦點(focus)時,我希望畫面能直接跳出書籤列表+瀏覽記錄。因為大部分情況下,使用者想要連結的網頁就是在這個還沒 filter 過的列表中,他可以直接點選就好,連輸入都可以省下來。
但是,原生的 AutoCompleteTextView
沒有任何調整的彈性。如果真的要改成這樣子的話,可能會需要把整個 AutoCompleteTextView 的原始碼複製一份到 EinkBro,再看有沒有機會去實作成這樣子的行為。之前稍微研究了一下,發現也無法用繼承的方式達成,就暫時擱著了。
現在,既然引入了 Compose,我就打算用 Compose 自己來刻一個,希望難度不會太高。實做的重點可以分成下面幾個部分:
因為整個 View 還是要先放入傳統的 Layout 中,為了整合上的方便,我還是把 Compose 的 AutoCompleteTextField
外層,包成 AutoCompleteTextComposeView
。
而 AutoCompleteTextField
則是分別由 TextInputBar
以及 BrowseHistoryList
所組成。我們先來聊聊 TextInputBar
。Compose 裡有提供 BasicTextField
元件,為了要處理 Enter 鍵和 focus 的處理,這裡特別再包了 TextInput
元件。因為內容有點瑣碎,在此跳過不提,大家可以自己看一下下面的相關連結。另外,為了要讓整個 text field 的右邊支援常用的清除鍵,以及隱藏鍵,這裡又包了 TextInputBar
。而且,在 175 行可以看到,如果使用者有 copy 過字串的話,這裡會接收到這資訊,額外長出一顆 paste 的按鈕,方便使用者直接貼上。
實作完 TextInputBar
之後,再來要處理 AutoComplete 的列表部分。32行代入的 List<Record>
就是符合字串的書籤列表和瀏覽記錄,而 RecordItem
則是用來呈現每個書籤的 icon 和標題。34 行的 shouldShowTwoColumns
,沒錯,當畫面比較大的時候,這個參數可以代入 true;這樣子一行就可以顯示兩筆記錄。
有了上述的兩個元件後,就可以來組成最外圈的 AutoCompleteTextField
了。115 行和 133 行分別再判斷需不需要 reverse。會這麼做的原因是:輸入列的顯示位置可以設定在畫面的最下方,或是最上方。如果是在最上方的話,在輸入網址的時候,自動補齊的列表應該要出現在輸入列的下方。反之,則是要呈現在輸入列的上方。
目前只想得到這種需要重覆兩段幾乎一樣程式碼的方式。如果大家有什麼好的建議,也歡迎留言跟我說。
實作好 View
之後,先把它加到既有的 Layout
當中。
(activity_main.xml)
再來就是在程式碼中初始化一下所需要的參數,大致上就完成了!是不是比想像中的簡單呢?
AutoCompleteTextComposeView 的 原始碼