[Android] TextView 分页功能的实现
為什么80%的碼農都做不了架構師?>>> ??
分頁功能是閱讀器類軟件的基本功能之一, 也是自己之前寫閱讀器時遇到的第一個問題. 嘗試了不少辦法才解決, 現在把其中最容易實現的一個方法記錄下來, 也方便大家參考.
基本思路如下:
整體思路很簡單, 其中唯一的難點就是第 4 步, 如何獲取 TextView 中的可見字數.
我遇到這類問題一般就是兩步走, 先文檔, 后源碼.
所以先去查 Android 文檔, 看看 TextView 有沒有什么可以利用的函數. 在其中找到一個函數:
getLineBounds(int line, Rect bounds) // 得到指定行的邊界
似乎有點用. 只要從第一行開始一行一行往下看, 直到找到超出邊界的那一行, 就能知道這個 TextView 能顯示多少行了. 或者用 getHeight() / getLineHeight() 也能獲取 TextView 的最大顯示行數. 但由于并不知道每行的字數, 所以還是算不出來一頁到底有多少字.
后來又嘗試了許多其他方法, 也在提問區問過. 結果只得到了一個建議, 就是自己寫個 View. 整個 View 都由自己實現的話, 的確能很方便地控制所有細節, 但隨之而來的麻煩就是, 所有的細節都得自己實現. 比如我的斷行, 和布局自適應這兩點處理得就沒原生的 TextView 那么好, 只能說勉強能用. 更別提超鏈接這類的東西了, 要想全部實現還真不是一時半會能搞定的.
既然查文檔無果, 那就只能去看源碼了. 不看不知道, 這不起眼的 Textview 源碼居然有近 9000 行, 頓時有點犯暈. 不過我的目標只有一個, 搞清楚 TextView 是怎么排版的. 所以直接看 onDraw(Canvas canvas) 函數, 在其中找到這么一行:
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
由此可以推斷 TextView 排版及繪制文字靠的就是這個 layout, 所以立刻到文檔中找 Layout, 這次終于在其中找到了幾個有用的函數(就是那些 getLine*** 函數), 最有用的是這兩個:
getLineForVertical(int vertical) // 根據縱坐標得到對應的行號
和
getLineEnd(int line) // 返回指定行中最后一個字在整個字符串中的位置
所以我們只要先計算出最下面一行是第幾行, 然后再算出這行最后一個字是第幾個字就行了.
先算行號:
public int getLineNum() {Layout layout = getLayout();int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight();return layout.getLineForVertical(topOfLastLine); }再算字數:
public int getCharNum() {return getLayout().getLineEnd(getLineNum()); }這樣我們就能得到 TextView 在本頁所顯示的字數了.
public class ReadView extends TextView {// 構造函數略...@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);resize();}/*** 去除當前頁無法顯示的字* @return 去掉的字數*/public int resize() {CharSequence oldContent = getText();CharSequence newContent = oldContent.subSequence(0, getCharNum());setText(newContent);return oldContent.length() - newContent.length();}/*** 獲取當前頁總字數*/public int getCharNum() {return getLayout().getLineEnd(getLineNum());}/*** 獲取當前頁總行數*/public int getLineNum() {Layout layout = getLayout();int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight();return layout.getLineForVertical(topOfLastLine);} }示例工程下載: http://pan.baidu.com/share/link?shareid=3043803389&uk=1563550261
轉載于:https://my.oschina.net/gotax/blog/136860
總結
以上是生活随笔為你收集整理的[Android] TextView 分页功能的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C语言实现的FFT与IFFT源代码,不依
- 下一篇: 简单两步干掉WordPress里面的fo