【Android】TextView設定段落間距
阿新 • • 發佈:2019-02-13
TextView只提供設定行距的方法,沒有提供段落間距的方法,但是提供了一個 SpannableString 類來給TextView設定各種效果,
如圖:
其中一個給文字替換為圖片的效果給我帶來了靈感,
我可以用一個圖片(最後換成一個寬1px,指定高度的透明長方形,xml中畫出來的)來模擬段落間距。
注意畫出來的高度,不能使用 用尺子直接量的值,而要比這個高度要小。
為什麼呢,我也不清楚,不過我還是要上個圖,我估計應該是兩行文字之間的line gap的原因。
後臺給我們返回的json中段落區分符是“\n”,我們先把”\n”替換為”\n\r”
“\n”用來換行,“\r”就是那個將要被替換的字元了(為什麼要用\r呢,陰差陽錯啦,後來發現\r挺合適的,也不會重複);最後就是用SpannableString來處理文字了。
/**
* 設定TextView段落間距
*
* @param context 上下文
* @param tv 給誰設定段距,就傳誰
* @param content 文字內容
* @param paragraphSpacing 請輸入段落間距(單位dp)
* @param lineSpacingExtra xml中設定的的行距(單位dp)
*/
public static void setParagraphSpacing(Context context, TextView tv, String content, int paragraphSpacing, int lineSpacingExtra) {
if (!content.contains("\n")) {
tv.setText(content);
return;
}
content = content.replace("\n", "\n\r");
int previousIndex = content.indexOf("\n\r");
//記錄每個段落開始的index,第一段沒有,從第二段開始
List<Integer> nextParagraphBeginIndexes = new ArrayList<>();
nextParagraphBeginIndexes.add(previousIndex);
while (previousIndex != -1) {
int nextIndex = content.indexOf("\n\r", previousIndex + 2);
previousIndex = nextIndex;
if (previousIndex != -1) {
nextParagraphBeginIndexes.add(previousIndex);
}
}
//獲取行高(包含文字高度和行距)
float lineHeight = tv.getLineHeight();
//把\r替換成透明長方形(寬:1px,高:字高+段距)
SpannableString spanString = new SpannableString(content);
Drawable d = ContextCompat.getDrawable(context, R.drawable.paragraph_space);
float density = context.getResources().getDisplayMetrics().density;
//int強轉部分為:行高 - 行距 + 段距
d.setBounds(0, 0, 1, (int) ((lineHeight - lineSpacingExtra * density) / 1.2 + (paragraphSpacing - lineSpacingExtra) * density));
for (int index : nextParagraphBeginIndexes) {
// \r在String中佔一個index
spanString.setSpan(new ImageSpan(d), index + 1, index + 2, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
tv.setText(spanString);
}
那個透明的長方形很簡單,隨手一畫就有了。
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@color/transparent"/>
</shape>
下邊這個就是替換後的效果,只不過這時候為了展示替換效果,那個長方形還是用了個orange色。