[Android] TextView 分頁功能的實現(xiàn)

摘要: 分頁功能是閱讀器類軟件的基本功能之一, 之前自己寫閱讀器時第一個遇到的問題就是這個. 也嘗試了不少辦法來解決這個問題, 現(xiàn)在把其中最容易實現(xiàn)的一個方法記錄下來, 也方便大家參考株憾。
本文轉(zhuǎn)載自:https://my.oschina.net/gotax/blog/136860

分頁功能是閱讀器類軟件的基本功能之一, 也是自己之前寫閱讀器時遇到的第一個問題. 嘗試了不少辦法才解決, 現(xiàn)在把其中最容易實現(xiàn)的一個方法記錄下來, 也方便大家參考.
基本思路如下:

  1. 從文件中讀取 8000 個字符至緩沖區(qū)
  2. 將表示位置的指針指向緩沖區(qū)開頭
  3. 讓 TextView 顯示從指針所指位置開始的內(nèi)容
  4. 獲取 TextView 中的可見字數(shù) n
  5. 將指針向后移動 n 位
  6. 向后翻頁時執(zhí)行 3 ~ 5 步

整體思路很簡單, 其中唯一的難點就是第 4 步, 如何獲取 TextView 中的可見字數(shù).
我遇到這類問題一般就是兩步走, 先文檔, 后源碼.
所以先去查 Android 文檔, 看看 TextView 有沒有什么可以利用的函數(shù). 在其中找到一個函數(shù):

getLineBounds(int line, Rect bounds)// 得到指定行的邊界

似乎有點用. 只要從第一行開始一行一行往下看, 直到找到超出邊界的那一行, 就能知道這個 TextView 能顯示多少行了. 或者用 getHeight() / getLineHeight() 也能獲取 TextView 的最大顯示行數(shù). 但由于并不知道每行的字數(shù), 所以還是算不出來一頁到底有多少字.

后來又嘗試了許多其他方法, 也在提問區(qū)問過. 結(jié)果只得到了一個建議, 就是自己寫個 View. 整個 View 都由自己實現(xiàn)的話, 的確能很方便地控制所有細節(jié), 但隨之而來的麻煩就是, 所有的細節(jié)都得自己實現(xiàn). 比如我的斷行, 和布局自適應(yīng)這兩點處理得就沒原生的 TextView 那么好, 只能說勉強能用. 更別提超鏈接這類的東西了, 要想全部實現(xiàn)還真不是一時半會能搞定的.

既然查文檔無果, 那就只能去看源碼了. 不看不知道, 這不起眼的 Textview 源碼居然有近 9000 行, 頓時有點犯暈. 不過我的目標只有一個, 搞清楚 TextView 是怎么排版的. 所以直接看 ``onDraw(Canvas canvas) 函數(shù), 在其中找到這么一行:

layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);

由此可以推斷 TextView 排版及繪制文字靠的就是這個 layout, 所以立刻到文檔中找 Layout, 這次終于在其中找到了幾個有用的函數(shù)(就是那些 getLine* 函數(shù)), 最有用的是這兩個:

getLineForVertical(int vertical)// 根據(jù)縱坐標得到對應(yīng)的行號

getLineEnd(int line)// 返回指定行中最后一個字在整個字符串中的位置

所以我們只要先計算出最下面一行是第幾行, 然后再算出這行最后一個字是第幾個字就行了.

先算行號:

public int getLineNum() {
    Layout layout = getLayout();
    int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight();
    return layout.getLineForVertical(topOfLastLine);
} ```

再算字數(shù):

public int getCharNum() {
return getLayout().getLineEnd(getLineNum());
}

這樣我們就能得到 TextView 在本頁所顯示的字數(shù)了.

    // 構(gòu)造函數(shù)略...
    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        resize();
    }

    /**
     * 去除當前頁無法顯示的字
     * @return 去掉的字數(shù)
     */
    public int resize() {
        CharSequence oldContent = getText();
        CharSequence newContent = oldContent.subSequence(0, getCharNum());
        setText(newContent);
        return oldContent.length() - newContent.length();
    }

    /**
     * 獲取當前頁總字數(shù)
     */
    public int getCharNum() {
        return getLayout().getLineEnd(getLineNum());
    }

    /**
     * 獲取當前頁總行數(shù)
     */
    public int getLineNum() {
        Layout layout = getLayout();
        int topOfLastLine = getHeight() - getPaddingTop() - getPaddingBottom() - getLineHeight();
        return layout.getLineForVertical(topOfLastLine);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末愈腾,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件望伦,死亡現(xiàn)場離奇詭異,居然都是意外死亡煎殷,警方通過查閱死者的電腦和手機屯伞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來豪直,“玉大人劣摇,你說我怎么就攤上這事」遥” “怎么了末融?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵,是天一觀的道長暇韧。 經(jīng)常有香客問我勾习,道長,這世上最難降的妖魔是什么懈玻? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任巧婶,我火速辦了婚禮,結(jié)果婚禮上涂乌,老公的妹妹穿的比我還像新娘艺栈。我一直安慰自己,他們只是感情好湾盒,可當我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布湿右。 她就那樣靜靜地躺著,像睡著了一般罚勾。 火紅的嫁衣襯著肌膚如雪毅人。 梳的紋絲不亂的頭發(fā)上漾唉,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音堰塌,去河邊找鬼。 笑死分衫,一個胖子當著我的面吹牛场刑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚪战,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼牵现,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了邀桑?” 一聲冷哼從身側(cè)響起瞎疼,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎壁畸,沒想到半個月后贼急,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡捏萍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年太抓,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片令杈。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡走敌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出逗噩,到底是詐尸還是另有隱情掉丽,我是刑警寧澤,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布异雁,位于F島的核電站捶障,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏片迅。R本人自食惡果不足惜残邀,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柑蛇。 院中可真熱鬧芥挣,春花似錦、人聲如沸耻台。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盆耽。三九已至蹋砚,卻和暖如春扼菠,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背坝咐。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工循榆, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人墨坚。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓秧饮,卻偏偏與公主長得像,于是被迫代替她去往敵國和親泽篮。 傳聞我的和親對象是個殘疾皇子盗尸,可洞房花燭夜當晚...
    茶點故事閱讀 42,762評論 2 345

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,501評論 25 707
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件帽撑、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,022評論 4 62
  • 在去南方的火車上泼各,作者注意到她旁邊的那位女子始終低著頭看著像是日記之類的記事本】骼或許她注意到了我的目光扣蜻,轉(zhuǎn)過頭來笑...
    我姓胡_閱讀 252評論 0 0
  • <想你一次是一粒沙是一滴水> 究竟想了你多少次 三毛說撒哈拉有多少粒沙 太平洋就有多少滴水 <寫詩> 我喜歡 一邊...
    凡高瀟湘花子閱讀 260評論 10 1
  • 今天是2017年1月29日星期天。 又是新的一年了专筷,可是這又怎們樣呢弱贼,能怎么樣呢,還不是白天一樣黑磷蛹,黑夜一樣光怪陸...
    七月我想啃西瓜閱讀 419評論 0 1