Android 解決TextView設置文本和富文本SpannableString自動換行留空白問題

TextView設置文本和富文本換行留白問題

效果圖對比

下面是設置普通文本的效果對比圖:

下面是設置富文本的效果對比圖:

解決方案

重新測量文字寬度,設置換行:

	private void initAutoSplitTextView() {
        mTv.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                mTv.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                final CharSequence newText = autoSplitText(mTv);
                if (!TextUtils.isEmpty(newText)) {
                    mTv.setText(newText);
                }
            }
        });
    }

    //返回CharSequence對象
    private CharSequence autoSplitText(final TextView tv) {
        //tv.getText(), 原始的CharSequence內容.
        CharSequence charSequence = tv.getText();
        final String rawText = tv.getText().toString(); //原始文本
        final Paint tvPaint = tv.getPaint(); //paint,包含字體等信息
        final float tvWidth = tv.getWidth() - tv.getPaddingLeft() - tv.getPaddingRight(); //控件可用寬度

        //將原始文本按行拆分
        String[] rawTextLines = rawText.replaceAll("\r", "").split("\n");
        StringBuilder newStringBuilder = new StringBuilder();
        for (String rawTextLine : rawTextLines) {
            if (tvPaint.measureText(rawTextLine) <= tvWidth) {
                //如果整行寬度在控件可用寬度之內,就不處理了
                newStringBuilder.append(rawTextLine);
            } else {
                //如果整行寬度超過控件可用寬度,則按字符測量,在超過可用寬度的前一個字符處手動換行
                float lineWidth = 0;
                for (int cnt = 0; cnt != rawTextLine.length(); ++cnt) {
                    char ch = rawTextLine.charAt(cnt);
                    lineWidth += tvPaint.measureText(String.valueOf(ch));
                    if (lineWidth <= tvWidth) {
                        newStringBuilder.append(ch);
                    } else {
                        newStringBuilder.append("\n");
                        lineWidth = 0;
                        --cnt;
                    }
                }
            }
            newStringBuilder.append("\n");
        }

        //把結尾多餘的\n去掉
        if (!rawText.endsWith("\n")) {
            newStringBuilder.deleteCharAt(newStringBuilder.length() - 1);
        }

        //對於有富文本的情況
        if (charSequence instanceof Spanned) {
            SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(charSequence);
            if (newStringBuilder.toString().contains("\n")) {
                String[] split = newStringBuilder.toString().split("\n");
                int tempIndex = 0;
                for (int i = 0; i < split.length; i++) {
                    if (i != split.length - 1) {
                        String s = split[i];
                        tempIndex = tempIndex + s.length() + i;
                        spannableStringBuilder.insert(tempIndex, "\n");
                    }
                }
            }
            return spannableStringBuilder;
        } else {
            return newStringBuilder;
        }

    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章