Android TextView 在指定位置自動省略字元

ETH_BOSS發表於2018-06-22

前言

我們都知道,Android中可以通過 android:ellipsize="xxx"來指定文字過長時的省略方式,但是這種方式只能侷限在文字後省略、文字前省略以及文字中央省略。

需求

有時候因為產品經理的需求,我們需要在指定的位置省略過長的文字。舉個例子,對於檔名來說,產品經理希望使用者能知道當前檔名的字尾,但是在檔案過長時又想省略檔名過長的部分,就會出現AAA...mp4這樣的顯示形式,這種顯示形式是無法通過設定android:ellipsize來實現的。

對於 "這可能是一個專門刁難程式設計師的很長的檔名.mp4"

  • 錯誤示範

    Android TextView 在指定位置自動省略字元

  • 正確示範

    Android TextView 在指定位置自動省略字元

解決方案

解決此問題的原理是通過textView.getPaint().measureText(String text)方法來獲取文字在TextView上所佔寬度。

  • 獲取原文字在控制元件上佔滿的長度
String originText = "這可能是一個專門刁難程式設計師的很長的檔名.mp4";
//獲取原文字長度
float originTextWidth = textView.getPaint().measureText(originText);
//獲取控制元件長度
float textViewWidth = textView.getWidth();
複製程式碼
  • 判斷控制元件是否可以裝滿文字
//控制元件長度大於文字長度 直接顯示
 if (textViewWidth >= originTextWidth) {
    textView.setText(originText);
}else {
    //獲取指定省略位置
}
複製程式碼
  • 獲取指定省略位置
 //獲取指定省略位置 對於檔名來說最後的"."是省略部分的標誌 
 int lastIndexOfPoint = originText.lastIndexOf(".");
 if (lastIndexOfPoint == -1) {
    //找不到 直接顯示
     textView.setText(originText);
 } else {
    //找到了 對字串切分
 }
複製程式碼
  • 根據省略位置對字串切分
//字首 檔名 "這可能是一個專門刁難程式設計師的很長的檔名"
String prefixText = originText.substring(0, lastIndexOfPoint);
//字尾 新增省略符號 "...mp4"
String suffixText = ".." + originText.substring(lastIndexOfPoint, originText.length());
複製程式碼

*不斷遞減指定位置前的字串,以此來獲取滿足條件的字首字串。

float prefixWidth = textView.getPaint().measureText(prefixText);
float suffixWidth = textView.getPaint().measureText(suffixText);

//字尾太長 不處理
if (suffixWidth > textViewWidth){
    textView.setText(originText);
}else {
    //每減少字首一個字元都去判斷是否能塞滿控制元件
    while (textViewWidth - prefixWidth < suffixWidth) {
        prefixText = prefixText.substring(0, prefixText.length() - 1);
        //關鍵
        prefixWidth = textView.getPaint().measureText(prefixText);
    }
    //能塞滿
    textView.setText(prefixText + suffixText);
}
複製程式碼

該方法滿足只顯示一行時需要省略指定位置的情況,多行的話可以加上行數進行進一步處理。

相關文章