半行文字顯示“查看更多”TailTextView

有一個(gè)需求

當(dāng)一個(gè)文本過長的時(shí)候會(huì)顯示很多行,為了顯示更多的信息(露出更多的view),會(huì)出現(xiàn)查看更多的需求。類似于下圖:


半行顯示查看更多

有一個(gè)想法

因?yàn)槭窃赥extView內(nèi)部處理這個(gè)事,所以一定要自定義TextView,把新的TextView叫做TailTextView。
大致思路如下:

  • 先使用maxLines屬性將TextView的理想高度測量出來
  • 找到最后一行字母的位置,加上查看更多,再加個(gè)顏色,調(diào)用一下回調(diào)方法
  • 重新使用setText,將新的CharSequence設(shè)置進(jìn)去

做一個(gè)實(shí)現(xiàn)

自定義屬性寫了兩個(gè):showTail(是否顯示小尾巴)和tailColor(尾巴顏色)
重寫onMeasure方法,先使用super的測量方法得到TextView每一行的布局
拿到TextView前maxLines-1行的文字,作為一定顯示的文字,最后一行作為要處理的文字
測量出小尾巴的寬度,將一行最大的寬度減去小尾巴寬度,得到原來文字最大寬度,使用這個(gè)寬度對(duì)最后一行文字進(jìn)行裁切。
在剛才得到的文字上加上“…查看更多”,設(shè)置span,回調(diào)被裁切方法。
將新的Text重新設(shè)置到TextView上。

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //不顯示小尾巴或者已經(jīng)處理過的不再處理
        if (!showTail || mEllipsizeFinal) {
            return;
        }
        int lineCount = getLineCount();
        Layout layout = getLayout();
        int maxLines = getMaxLines();
        //行數(shù)沒有到maxLines不處理
        if (maxLines == 0 || lineCount < maxLines || TextUtils.isEmpty(getText())){
            return;
        }
        //一共的文字?jǐn)?shù)量
        int totalChars = layout.getLineEnd(maxLines - 1);
        int lastLineStartIndex = layout.getLineStart(maxLines - 1);

        if (totalChars >= getText().length()) {
            return;
        }
        CharSequence mustShowText = getText().subSequence(0, lastLineStartIndex);

        String tailText = "…查看全文";
        float tailWidth = getPaint().measureText(tailText);
        CharSequence lastLineText;
        int screenWidth = DeviceUtils.getScreenWidth(getContext());
        //最后一個(gè)字是個(gè)換行符就把這個(gè)換行符去掉,不然不能在那一行后面增加文字了
        if (LINE_BREAKER.equals(String.valueOf(getText().charAt(totalChars - 1)))) {
            lastLineText = getText().subSequence(lastLineStartIndex, totalChars - 1);
        } else {
            lastLineText = getText().subSequence(lastLineStartIndex, totalChars);
        }
        //這里可能會(huì)出現(xiàn)每一行都有換行符,然后整個(gè)TextView的寬度很小的情況
        //對(duì)可能超過右邊進(jìn)行修正,screenWidth * 0.6f是應(yīng)該可以調(diào)整的
        float maxWidth = Math.max(screenWidth * 0.6f, getMeasuredWidth());
        CharSequence ellipsizeLastLineText = TextUtils.ellipsize(lastLineText, getPaint(), maxWidth - tailWidth,
            TextUtils.TruncateAt.END);
        if (ellipsizeLastLineText.length() > 2 && ellipsizeLastLineText != lastLineText) {
            lastLineText = ellipsizeLastLineText.subSequence(0, ellipsizeLastLineText.length() - 1);
        }

        SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(mustShowText);
        spannableStringBuilder.append(lastLineText);
        int start = spannableStringBuilder.length();
        spannableStringBuilder.append(tailText);
        spannableStringBuilder.setSpan(new ForegroundColorSpan(tailColor), start + 1, start + 5,
            Spannable.SPAN_INCLUSIVE_INCLUSIVE);
        //重新設(shè)置文本
        super.setText(spannableStringBuilder);
        //每設(shè)置一次text要重置一個(gè)這個(gè)位。重寫setText(在里面重新置位)
        mEllipsizeFinal = true;
        onEllipsize();//回調(diào)是否被裁切
    }

效果就是上面放的圖了。

寫一些Tips

設(shè)置maxLines屬性之后就不要設(shè)置ellipsize="end"了,可能會(huì)引起最后一行的寬度測量不準(zhǔn)確。
screenWidth * 0.6f有點(diǎn)草率,可以修改的
如果要使用原來的maxLines屬性的功能就設(shè)置showTail為false
沒有給出TailTextView的全文,但核心內(nèi)容就是這些了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本篇文章已授權(quán)微信公眾號(hào) 安卓巴士Android開發(fā)者門戶 獨(dú)家發(fā)布 老規(guī)矩,先上張圖o,這篇好像是分析篇,沒有效...
    請(qǐng)叫我大蘇閱讀 14,654評(píng)論 1 43
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 15,360評(píng)論 4 61
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,568評(píng)論 19 139
  • “會(huì)長,找到龍王復(fù)活的名山了?!笨諘绲霓k公室內(nèi),一名學(xué)生正匯報(bào)著他所知道的一切。“哦,這么快”聽到下屬的匯...
    暮慟閱讀 342評(píng)論 0 1
  • 名稱:異國風(fēng)情 材料:皺紋紙、彩色紙、雙面膠(大小卷)、剪刀、鉛筆、橡皮、卡紙(背景紙)。 步驟:①選出底色卡紙做...
    許琳琳_閱讀 449評(píng)論 0 3

友情鏈接更多精彩內(nèi)容