Android?14新功能HighLights快速實現(xiàn)文本高亮
正文
日常開發(fā)中可能會遇到給 TextView 的全部或部分文本增加高亮效果的需求,以前可能是通過 Spannable
或者 Html
標簽實現(xiàn)。
升級 Android 14 后就不用這么迂回了,因其首次引入直接設置高亮的 API:HighLights
。需要留意的是 HighLights API 和 Android 1.0 即加入的 textColorHighlight
API 不同:
- 14 的新 API 就是文本在 normal 狀態(tài)下的高亮,之前這個是為了設置選中時文本高亮,
- 14 的新 API 只提供了 get/set 方法,沒有提供與之匹配的 attribute。而之前的 API還提供了 android:
textColorHighlight
attribute 配置
下面我們就來一探這個新 API 的玩法和 textColorHighlight API 的區(qū)別。
目錄前瞻:
- 設置高亮
- 獲取高亮
- 動態(tài)更新高亮
- 與選中時效果是否沖突
- 結語
1. 設置高亮
HighLights
采用的是熟知的建造者模式,即首先需要構建不同參數(shù)的 Builder
實例,針對參數(shù)也提供了兩種設置方式:
一次指定單組高亮配置:addRange(Paint paint, int start, int end),如果多組需要設置同樣高亮顏色的話,那要調用多次
一次指定多組高亮配置:addRange(Paint paint, int... ranges),如果多組需要設置同樣高亮顏色的話,只要調用一次即可
既然是多組范圍那么 int 參數(shù)必須是偶數(shù)數(shù)目的,即成對出現(xiàn),反之會發(fā)生如下的 Exception:
java.lang.IllegalArgumentException: Flatten ranges must have even numbered elements
可以說上述兩個 API 的參數(shù)都是成對出現(xiàn),對于高亮的響應范圍的話:前者是包含 inclusive 在內的,后者是不包含 exclusive 在內的,需要注意。
我們通過代碼實例演示通過上述兩個 Builder API 構建一樣的高亮效果,然后通過 TextView
的 setHighLights()
反映。
class MainActivity : AppCompatActivity() { companion object { const val TEXT = "val builder = Highlights.Builder()" } override fun onCreate(savedInstanceState: Bundle?) { ... val yellowPaint = Paint().apply { color = Color.YELLOW } val greenPaint = Paint().apply { color = Color.GREEN } with(binding.textview1) { text = TEXT val builder = Highlights.Builder() .addRange(yellowPaint, 0, 3) .addRange(greenPaint, 14, 24) .addRange(greenPaint, 25, 32) highlights = builder.build() } with(binding.textview2) { text = TEXT val builder = Highlights.Builder() .addRanges(yellowPaint, 0, 3) .addRanges(greenPaint, 14, 24, 25, 32) highlights = builder.build() } } }
可以看到不同的 Builder 參數(shù)設置方式可以對 val 設置黃色高亮,Highlights 和 Builder 設置綠色高亮。
2. 獲取高亮
設置到 TextView 對象的 HighLights 實例還可以通過 getHighlights()
獲取,并通過如下的 API 獲取高亮的細節(jié):
首先通過 getSize()
獲取設置高亮的數(shù)量
其次從 0 開始遍歷下標
- 通過
getPaint(int index)
獲取高亮的Paint
對象 - 以及通過
getRanges(int index)
獲取對應的 Paint 范圍Ranges
(也是一個數(shù)組,需要遍歷打印具體的起始位置)
class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... binding.textview1.highlights?.run { Log.d("HighLights", "textview1 usedHighLights' size:$size") for (i in 0 until size) { Log.d("HighLights", "usedHighLights'" + " paint:${getPaint(i).color.toColorString()}") val range = getRanges(i) for (j in range.indices) { Log.d("HighLights", "ranges:${range[j]}") } } } binding.textview2.highlights?.run { Log.d("HighLights", "textview2 usedHighLights' size:$size") for (i in 0 until size) { Log.d("HighLights", "usedHighLights'" + " paint:${getPaint(i).color.toColorString()}") val range = getRanges(i) for (j in range.indices) { Log.d("HighLights", "ranges:${range[j]}") } } } } }
如下的 log 可以看到打印出來的 Paint 顏色、范圍 Ranges 和設置的參數(shù)是一一對應的。
03-23 23:08:27.196 7182 7182 D HighLights: textview1 usedHighLights' size:3
03-23 23:08:27.196 7182 7182 D HighLights: usedHighLights' paint:YELLOW
03-23 23:08:27.196 7182 7182 D HighLights: ranges:0
03-23 23:08:27.196 7182 7182 D HighLights: ranges:3
03-23 23:08:27.196 7182 7182 D HighLights: usedHighLights' paint:GREEN
03-23 23:08:27.196 7182 7182 D HighLights: ranges:14
03-23 23:08:27.196 7182 7182 D HighLights: ranges:24
03-23 23:08:27.196 7182 7182 D HighLights: usedHighLights' paint:GREEN
03-23 23:08:27.196 7182 7182 D HighLights: ranges:25
03-23 23:08:27.196 7182 7182 D HighLights: ranges:32
03-23 23:08:27.196 7182 7182 D HighLights: textview2 usedHighLights' size:2
03-23 23:08:27.196 7182 7182 D HighLights: usedHighLights' paint:YELLOW
03-23 23:08:27.196 7182 7182 D HighLights: ranges:0
03-23 23:08:27.196 7182 7182 D HighLights: ranges:3
03-23 23:08:27.196 7182 7182 D HighLights: usedHighLights' paint:GREEN
03-23 23:08:27.196 7182 7182 D HighLights: ranges:14
03-23 23:08:27.196 7182 7182 D HighLights: ranges:24
03-23 23:08:27.196 7182 7182 D HighLights: ranges:25
03-23 23:08:27.196 7182 7182 D HighLights: ranges:32
3. 動態(tài)更新高亮
既然我們可以獲取已經設置的 HighLights,那么更新其屬性,能否動態(tài)更新高亮效果呢?
首先在 TextView 下添加動態(tài)更新 HighLights 的 Button
- 然后點擊該 Button 之后將 textView1 的 Paint 顏色從 GREEN 改為 BLUE,并將其中 “Highlights” 的文本范圍增大:頭尾各擴展一個或多個下標
class MainActivity : AppCompatActivity() { ... override fun onCreate(savedInstanceState: Bundle?) { ... binding.changeHighlights.setOnClickListener { Log.d("HighLights", "changeHighlights tapped & change highlights") textView1Highlights?.apply { // Change color getPaint(1).color = Color.BLUE // Change ranges getRanges(1)[0] -= 3 getRanges(1)[1] += 1 for (i in 0 until size) { Log.d("HighLights", "textView1Highlights'" + " paint:${getPaint(i).color.toColorString()}") val range = getRanges(i) for (j in range.indices) { Log.d("HighLights", "ranges:${range[j]}") } } } binding.textview1.invalidate() } } }
點擊 Button 之后,顏色確實變成了藍色,但是高亮范圍卻沒有變化。
我們打印的更新后 HighLights 的參數(shù) log:可以看到,無論是顏色(GREEN -> BLUE)還是范圍(14 -> 11,24 -> 25)確實都已經更改了。
可為什么唯獨 Ranges 沒有刷新?有可能是 14 預覽版階段的 Bug。
03-25 10:47:29.276 5344 5344 D HighLights: changeHighlights tapped & change highlights
03-25 10:47:29.276 5344 5344 D HighLights: textview1 textView1Highlights' size:3
03-25 10:47:29.276 5344 5344 D HighLights: textView1Highlights' paint:YELLOW
03-25 10:47:29.276 5344 5344 D HighLights: ranges:0
03-25 10:47:29.276 5344 5344 D HighLights: ranges:3
03-25 10:47:29.277 5344 5344 D HighLights: textView1Highlights' paint:BLUE
03-25 10:47:29.277 5344 5344 D HighLights: ranges:11
03-25 10:47:29.277 5344 5344 D HighLights: ranges:25
03-25 10:47:29.277 5344 5344 D HighLights: textView1Highlights' paint:BLUE
03-25 10:47:29.277 5344 5344 D HighLights: ranges:25
03-25 10:47:29.277 5344 5344 D HighLights: ranges:32
4. 與選中時效果是否沖突
我們給上述其中一個 TextView 添加選中高亮顏色的配置即 textColorHighlight
,該顏色與上述 HighLights 顏色不同,以清晰地判斷兩種高亮是否會發(fā)生沖突。
注意需要將 textIsSelectable
設置為 true,這樣 TextView 才可以被長按選中。
<androidx.constraintlayout.widget.ConstraintLayout ... > <TextView android:id="@+id/textview1" ... android:textColorHighlight="@color/purple_200" android:textIsSelectable="true" ... /> < ... > </androidx.constraintlayout.widget.ConstraintLayout>
我們在該 TextView 上長按看一下效果:
可以看到水滴選中的范圍內會變成我們設置的 textColorHighlight 紫色高亮,未選中的部分會按照 HighLights 配置的那樣展示黃色和綠色以及沒有設置 HighLights 的默認淺灰色。
5. 結語
可以看到新功能 HighLights
可以使得高亮的處理變得簡單、易用,大家可以在 14 上采用該 API,當高版本普及后,低版本上的自定義高亮邏輯就可以舍棄了。
至于其原理,因為 Android 14 尚處于預覽版階段、源碼沒有公開,無法獲悉實現(xiàn)。但估計是 TextView
在 draw
階段會獲取設置的 HighLights 包含的 size 以及對應的 Paint
和 Ranges
,得以清晰地掌握各高亮的顏色和對應的范圍,然后直接調用 Canvas
的 drawText(text, start, end, x, y, paint)
去完成繪制。
可以說 HighLights 這種 API 既方便了開發(fā)者的使用:從設置
高亮到獲取
高亮到動態(tài)更新
高亮,其清晰的邏輯一定程度上也可以簡化 SDK 的實現(xiàn)。
事實上 Android 14 還針對 TextView
做了其他新功能的支持,比如設置文內搜索結果的文本高亮、索引,后續(xù)一并進行解讀:
- setSearchResultHighlightColor(int color):設置所有匹配到搜索關鍵字的文本顏色
- setSearchResultHighlights(int... ranges):設置所有匹配到搜索關鍵字的文本高亮
HighLights
的范圍 - setFocusedSearchResultHighlightColor(int color):設置當前聚焦到的匹配關鍵字的文本顏色
- setFocusedSearchResultIndex(int index):設置當前聚焦到的匹配關鍵字的索引
參考
以上就是Android 14新功能HighLights快速實現(xiàn)文本高亮的詳細內容,更多關于Android HighLights文本高亮的資料請關注腳本之家其它相關文章!
相關文章
Android實現(xiàn)短信加密功能(發(fā)送加密短信、解密本地短信)
這篇文章主要介紹了android實現(xiàn)短信加密功能的相關資料,功能包括發(fā)送加密短信、解密本地短信,感興趣的小伙伴們可以參考一下2016-01-01Android?studio開發(fā)實現(xiàn)計算器功能
這篇文章主要為大家詳細介紹了Android?studio開發(fā)實現(xiàn)計算器功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05Flutter?+?Idea?環(huán)境搭建及配置教程
本文主要總結我實際搭建的過程,最后發(fā)現(xiàn)不一定按網上那些博客或者官方文檔寫的來也可以搭建成功,在這里小編給大家分享下Flutter?+?Idea?環(huán)境搭建及配置教程,感興趣的朋友參考下吧2021-12-12Android應用開發(fā):電話監(jiān)聽和錄音代碼示例
這篇文章主要介紹了Android應用開發(fā)中電話監(jiān)聽和電話錄音的代碼實例,同時附錄了一個拍照、錄像的例子,需要的朋友可以參考下2014-04-04Android TextView實現(xiàn)多文本折疊、展開效果
這篇文章主要為大家詳細介紹了Android TextView實現(xiàn)多文本折疊、展開效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-05-05