<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
日常開發中可能會遇到給 TextView 的全部或部分文字增加高亮效果的需求,以前可能是通過 Spannable
或者 Html
標籤實現。
升級 Android 14 後就不用這麼迂迴了,因其首次引入直接設定高亮的 API:HighLights
。需要留意的是 HighLights API 和 Android 1.0 即加入的 textColorHighlight
API 不同:
textColorHighlight
attribute 設定下面我們就來一探這個新 API 的玩法和 textColorHighlight API 的區別。
目錄前瞻:
HighLights
採用的是熟知的建造者模式,即首先需要構建不同引數的 Builder
範例,針對引數也提供了兩種設定方式:
一次指定單組高亮設定:addRange(Paint paint, int start, int end),如果多組需要設定同樣高亮顏色的話,那要呼叫多次
一次指定多組高亮設定:addRange(Paint paint, int... ranges),如果多組需要設定同樣高亮顏色的話,只要呼叫一次即可
既然是多組範圍那麼 int 引數必須是偶數數目的,即成對出現,反之會發生如下的 Exception:
java.lang.IllegalArgumentException: Flatten ranges must have even numbered elements
可以說上述兩個 API 的引數都是成對出現,對於高亮的響應範圍的話:前者是包含 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 引數設定方式可以對 val 設定黃色高亮,Highlights 和 Builder 設定綠色高亮。
設定到 TextView 物件的 HighLights 範例還可以通過 getHighlights()
獲取,並通過如下的 API 獲取高亮的細節:
首先通過 getSize()
獲取設定高亮的數量
其次從 0 開始遍歷下標
getPaint(int index)
獲取高亮的 Paint
物件getRanges(int index)
獲取對應的 Paint 範圍 Ranges
(也是一個陣列,需要遍歷列印具體的起始位置)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 和設定的引數是一一對應的。
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
既然我們可以獲取已經設定的 HighLights,那麼更新其屬性,能否動態更新高亮效果呢?
首先在 TextView 下新增動態更新 HighLights 的 Button
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 的引數 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
我們給上述其中一個 TextView 新增選中高亮顏色的設定即 textColorHighlight
,該顏色與上述 HighLights 顏色不同,以清晰地判斷兩種高亮是否會發生衝突。
注意需要將 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 的預設淺灰色。
可以看到新功能 HighLights
可以使得高亮的處理變得簡單、易用,大家可以在 14 上採用該 API,當高版本普及後,低版本上的自定義高亮邏輯就可以捨棄了。
至於其原理,因為 Android 14 尚處於預覽版階段、原始碼沒有公開,無法獲悉實現。但估計是 TextView
在 draw
階段會獲取設定的 HighLights 包含的 size 以及對應的 Paint
和 Ranges
,得以清晰地掌握各高亮的顏色和對應的範圍,然後直接呼叫 Canvas
的 drawText(text, start, end, x, y, paint)
去完成繪製。
可以說 HighLights 這種 API 既方便了開發者的使用:從設定
高亮到獲取
高亮到動態更新
高亮,其清晰的邏輯一定程度上也可以簡化 SDK 的實現。
事實上 Android 14 還針對 TextView
做了其他新功能的支援,比如設定文內搜尋結果的文字高亮、索引,後續一併進行解讀:
HighLights
的範圍參考
以上就是Android 14新功能HighLights快速實現文字高亮的詳細內容,更多關於Android HighLights文字高亮的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45