<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
相信這個方法Canvas.drawText大家一定不陌生,TextView就是使用它將文字繪製出來。可是這個方法並沒有文字換行的功能,也就是說它只能繪製一行;但是TextView的文字卻是會自動換行,當頁面不足以顯示後面的文字時(通過android:breakStrategy屬性可以調整換行時機)就會自動換行。檢視原始碼後發現TextView是通過Layout來幫助測量文字。
Layout是一個抽象類,具體實現有BoringLayout、StaticLayout、DynamicLayout。 簡單介紹一下:
這裡通過StaticLayout來介紹一下它們的作用。
val lineSpaceadd = 0.0f //額外的行間距 val lineSpacemuti = 1.0f//行間距倍數 //根據不同的版本確認是否使用Builder if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) { mLayout = StaticLayout.Builder .obtain("傳入的String", string的起始座標, string的結尾座標, TextPaint(), width) .build() } else { //傳統構造方法 mLayout = StaticLayout( "傳入的String", TextPaint(), width, Layout.Alignment.ALIGN_NORMAL, lineSpaceadd, lineSpacemuti, false ) }
我們可以用它來幹嘛呢
Layout通過傳入的String和width,來計算出每行能顯示的文字數量。所以我們能夠獲取每一行的文字。
mLayout.lineCount//獲取行數 mLayout.getLineStart(0)//獲取第一行在傳入String中的起始位置 mLayout.getLineEnd(0)//獲取第一行在傳入String中的終止位置 mLayout.getLineVisibleEnd(2)//獲取指定行的最後可見字元(不計算空格的文字偏移量)
Layout有一個draw方法,可以直接把分行的內容繪製到view上。
val canvas = getCanvas() mLayout.draw(canvas)//傳入canvas就行啦
開發了小說的閱讀軟體,我需要將每一章的內容分配到每一個頁面。我需要獲取到每一頁能夠顯示的文字數量和文字內容。
此時就可以通過Layout把章節內容分行,然後計算每一頁能夠顯示多少行,將每頁的內容傳遞過去。
簡單描述一下這個分頁工具:
需要傳入章節的內容,因為要進行分頁,肯定是需要它的。
行間距相關的兩個引數
lineSpaceAdd 額外的行間距,正數則增加行間距負數則減少,預設為0.0f。
lineSpaceMutil 行間距倍數,沒有具體的單位,預設為1.0f,大於1.0f則增加行距,小於則減少。
這兩個引數在小說閱讀頁面還是很重要的。 3. 閱讀頁面的高度和寬度,通過寬度使得Layout能夠將內容分割成行,通過頁面高度和行高度就能夠能夠獲取每一頁能夠顯示的行數。 4. 行高度lineHeight
如果你是直接傳遞的textview來計算的話就是直接textview.getLineHeight()
如果是通過傳遞textPaint,那麼就用這個計算
fun getLineHeight(): Float { //公式很簡單,也體現出了行間距這兩個引數的作用 return textPaint.textSize * lineSpaceMult + lineSpaceExtra }
光有這些東西當然是不夠的,文字的測量肯定需要知道文字的字型、字號,在這裡只需要傳入一個TextPaint就可以獲取到這些資料了。
PagingTool.kt 我糾結了很久最後還是用了單例模式,程式碼功底不深,有問題歡迎大家指出。
//kotlin中的單例,java的同學不用納悶 object PagingTool{ private var width = 0//寬度 private var height = 0//高度 private var lineSpaceAdd = 0.0f//額外的行間距 private var lineSpaceMutil = 1.0f//行間距倍數 private var text:String = ""//文字內容 private var textPaint = TextPaint() //對於畫筆的引數,由於我是把閱讀頁面的設定儲存在資料庫中的,通過room框架返回LiveData,實時更新字型字號;當然也可以每次設定變更就手動更新一次。 private lateinit var mLayout:Layout//工具的核心人物,lateinit就是延遲載入的意思, //setter public fun setHeight(height: Int) { this.height = height } public fun setWidth(width: Int) { this.width = width } public fun setPaint(textPaint:TextPaint){ this.textPaint = textPaint } public fun setLineSpaceAdd(spaceAdd:Float){ lineSpaceAdd = spaceAdd } public fun setLineSpaceMutil(spaceMutil:Float){ lineSpaceMutil = spaceMutil } //計算行高 private fun getLineHeight():Int{ //上面說到的計算方法 return textPaint.textSize*lineSpaceMutil+lineSpaceAdd //textView.getLineHeight() } private fun setText(str:String){ text = str mLayout = StaticLayout( text, textPaint, width, Layout.Alignment.ALIGN_NORMAL, lineSpaceAdd, lineSpaceMutil, false//這個引數不用在意 ) } //分頁 public fun paging(str:String):List<String>{ setText(str)//設定內容,初始化layout //邊界條件,為0就直接返回整個章節的內容 if(width == 0 || height == 0)return arrayListOf(str) val totalLineCount = mLayout.lineCount//總行數,這個是layout測量出來的 var pageLineCount = height / getLineHeight() //頁面高度除以行高度得到頁面允許繪製的行數 if(pageLineCount < 1)pageLineCount = 1//這種情況,只可能出現在文字巨大,大到頁面高度顯示不下一行文字,那我還是設定讓他顯示一行,可以刪掉 var pageCount = totalLineCount / pageLineCount //總行數除以頁面允許繪製的行數,得到分頁數量 if (totalLineCount % pageLineCount > 0)//還剩下有幾行,組成最後一頁 pageCount++ val list = ArrayList<String>() //現在就只需要將內容按頁新增到這個list中 for(i in 0 until pageCount){ var temp = (i + 1) * pageLineCount temp-- if (temp >= totalLineCount) temp = totalLineCount - 1 val start = mLayout.getLineStart(i * pageLineCount) val end = mLayout.getLineEnd(temp) //獲取到每一頁的起始座標,結尾座標 val string = text.substring(start, end) list.add(string) } //這個時候就已經把內容分頁了,list的size就是頁數 return list } }
手擼的,沒有跑過大致思路是這樣,也許會有小bug,大問題應該沒有吧,看個思路就好,更多關於Android開發TextView自動換行的資料請關注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