Android 解決TextView設定文字和富文字SpannableString自動換行留空白問題
阿新 • • 發佈:2021-01-18
技術標籤:Android開發TextView自動換行Android 富文字
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; } }