March 13, 2012
Android Clickable Span in TextView
Spannable 可以讓一個 TextView 顯示不同外觀的字串,也可以加入 Click 事件的 callback。
通常想讓 TextView 觸發 Click 事件,最直接的正規作法就是 View.setOnCilckListener。倘若運氣不好,遇上一些比較奇怪的需求,例如一串文字的某一部份用一種顏色,另外一部份使用其他顏色,而這兩者同時都要能夠 Click。
這樣的需求能以 ViewGroup + TextView 完成,但更進一步的問:是否用一個 TextView 就解決?解答就會導向 Spanned/Spannable
不知道 Span 該如何翻譯,單從功能上來看,Span 是賦予一段文字(CharSequence)額外的能力。舉例來說我有一個字串 TheFinalAnswerIs42,我希望 Final 的部份以紅色顯示,42 的部份可以被 click,就是把 ForegroundColorSpan 設給 Final,ClickableSpan 設給 42,如此一來,TextView 仍然是顯示這一段文字,內容卻變得更加豐富。
先看看物件之間的關係,Spanned 介面繼承了 CharSequence,Spannable 介面繼承了 CharSequence,TextView.setText 的對象是 CharSequence,因此所有的 Spanned/Spannable 都可以直接放入 TextView 而不會出錯。因此問題簡化成如何從一個 String 變出我們需要的 Span。
查閱 Android 本草綱目,利用 SpannableStringBuilder 產生 SpannableString
如此一來,這個字串的其中一部分就被賦予了變色的能力,如果要使其成為 clickable
最技巧的部份就是 setSpan,使用的對象是最原始的 Object 而非比較嚴謹的 Spanned 之類介面,本草綱目也說你可以任意綁上自己定義的物件,問題就在此:TextView 怎麼知道如何用我定義的物件?反過來想,TextView 是如何使用 ClickableSpan?
簡單挖一下 TextView 的 source code 即可明白:TextView 的 onTouchEvent 有針對 ClickableSpan 做處理。換句話說自己定義的 Span 無法被 TextView 認得,必須繼承 TextView,針對自己的 Span 做處理,至於 Api 裡頭提供的 Spannable,TextView 應該都已經認得,不須擔心。
於是,一個原本單調的 TextView,賦予 Span 進去之後就會開始變得多采多姿。
通常想讓 TextView 觸發 Click 事件,最直接的正規作法就是 View.setOnCilckListener。倘若運氣不好,遇上一些比較奇怪的需求,例如一串文字的某一部份用一種顏色,另外一部份使用其他顏色,而這兩者同時都要能夠 Click。
這樣的需求能以 ViewGroup + TextView 完成,但更進一步的問:是否用一個 TextView 就解決?解答就會導向 Spanned/Spannable
不知道 Span 該如何翻譯,單從功能上來看,Span 是賦予一段文字(CharSequence)額外的能力。舉例來說我有一個字串 TheFinalAnswerIs42,我希望 Final 的部份以紅色顯示,42 的部份可以被 click,就是把 ForegroundColorSpan 設給 Final,ClickableSpan 設給 42,如此一來,TextView 仍然是顯示這一段文字,內容卻變得更加豐富。
先看看物件之間的關係,Spanned 介面繼承了 CharSequence,Spannable 介面繼承了 CharSequence,TextView.setText 的對象是 CharSequence,因此所有的 Spanned/Spannable 都可以直接放入 TextView 而不會出錯。因此問題簡化成如何從一個 String 變出我們需要的 Span。
查閱 Android 本草綱目,利用 SpannableStringBuilder 產生 SpannableString
Spannable span = (new SpannableStringBuilder()).newSpannable("TheFinalAnswerIs42");
span.setSpan(new ForegroundColorSpan(0xFFFF0000), 3, 5,Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
如此一來,這個字串的其中一部分就被賦予了變色的能力,如果要使其成為 clickable
span.setSpan(new MyClickableSpan(), 16, text.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); mTextView.setText(span); mTextView.setMovementMethod(LinkMovementMethod.getInstance());MyClickableSpan 是繼承 ClickableSpan 的實作,只要覆寫 onClick 即可。
最技巧的部份就是 setSpan,使用的對象是最原始的 Object 而非比較嚴謹的 Spanned 之類介面,本草綱目也說你可以任意綁上自己定義的物件,問題就在此:TextView 怎麼知道如何用我定義的物件?反過來想,TextView 是如何使用 ClickableSpan?
簡單挖一下 TextView 的 source code 即可明白:TextView 的 onTouchEvent 有針對 ClickableSpan 做處理。換句話說自己定義的 Span 無法被 TextView 認得,必須繼承 TextView,針對自己的 Span 做處理,至於 Api 裡頭提供的 Spannable,TextView 應該都已經認得,不須擔心。
於是,一個原本單調的 TextView,賦予 Span 進去之後就會開始變得多采多姿。
Subscribe to:
Posts (Atom)


