之前做 LeafLoadingView 的時候罢杉,進度到達 100 后,需要將風扇替換為文字瘟判。這里的文字當時還是讓我頭疼了一會的怨绣,不過最終用縮放解決了問題。這讓我不禁想拷获,安卓 sdk 中肯定有繪制 text 的 api 我不知道篮撑,否則繪制文字的時候難點太多了。如果要我自己實現(xiàn)一個簡易版的 TextView 根本不可能匆瓜。
機緣巧合的某天赢笨,我在 github 上看一個項目,正巧看到了他們實現(xiàn)一個自定義 View 時測量文本用的方法陕壹,看起來挺好用的质欲,google 了一下树埠,今天學習了糠馆。
測量單行文本
這個技能相信大部分有過自定義 View 經(jīng)歷的人都學習過了,如果你有一個單行文本需要測量怎憋,那么通常你可以使用 TextPaint
或者 Paint
來測量又碌。
例如:
String text = "This is some text."
TextPaint myTextPaint = new TextPaint();
mTextPaint.setAntiAlias(true);
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
mTextPaint.setColor(0xFF000000);
float width = mTextPaint.measureText(text);
float height = -mTextPaint.ascent() + mTextPaint.descent();
同樣的,由于是單行文本绊袋,我們也不需要做換行操作毕匀,因此只要直接利用 drawText 方法繪制上去就可以了。這樣的需求十分簡單癌别,相信即使沒有接觸過自定義 TextView皂岔, 也可以很快完成。
如果你是在界面代碼中需要測量文本長度的話展姐,那么下面的代碼或許可以幫到你:
//在界面代碼中測量文本
// 1. 對于顯示在已知 TextView 上的文本
Paint paint = textView.getPaint();
// 2. 對于普通的文本
Paint paint = new Paint();
//... 設置各種顯示的屬性
// 獲取到 Paint 對象之后躁垛,剩下的測量方式,請參考上面的代碼
測量多行文本 - StaticLayout
我們知道利用 drawText
方法繪制文字圾笨,是不會自動換行的教馆。如果文本超出容器的限制,多余的部分在屏幕上是不會顯示的擂达。因此土铺,如果要利用 drawText
繪制長文本,需要計算長度進行文本截取和換行繪制的操作板鬓。這個過程稍微想象一下就讓人怠惰起來一點也沒有干勁悲敷。
這里就該提到我之前說到的新學習的類了—— StaticLayout。StaticLayout 封裝了許多有用的方法俭令,同時它也支持自動換行镀迂。事實上,TextView 中也使用到了 StaticLayout唤蔗。
StaticLayout 的構造器中需要傳入許多參數(shù)探遵,剛剛見到的時候可以說是一頭霧水窟赏。下面讓我們來介紹一下各個參數(shù)的含義:
StaticLayout(
CharSequence source, //1.需要分行的字符串
int bufstart, //2.需要分行的字符串從第幾的位置開始
int bufend, //3.需要分行的字符串到哪里結束
TextPaint paint, //4.畫筆對象
int outerwidth, //5.layout的寬度,字符串超出寬度時自動換行
Alignment align, //6.layout的對其方式箱季,有ALIGN_CENTER涯穷, ALIGN_NORMAL, ALIGN_OPPOSITE 三種
float spacingmult, //7.相對行間距藏雏,相對字體大小拷况,1.5f表示行間距為1.5倍的字體高度
float spacingadd, //8.在基礎行距上添加多少
boolean includepad, //9.是否包含文字上下的空余部分,在某些語言下掘殴,切割這些空余部分會導致顯示不全赚瘦,默認為true
TextUtils.TruncateAt ellipsize, //10.從什么位置開始省略 TextUtils.TruncateAt
int ellipsizedWidth, //11.超過多少開始省略,這個值僅用于省略奏寨,不影響 Layout 的寬度
int maxLine //12.最大行數(shù)
)
上面的參數(shù)如果覺得不夠清楚起意,可以查看源碼。在 api 23 之后病瞳,加入了 Builder 的鏈式構造揽咕,每個構造方法中都有參數(shù)的說明,查看十分方便套菜。
構造好之后亲善,就可以直接利用 getHeight
方法計算出 Layout 的高度了。
String text = "This is some text. This is some text. This is some text. This is some text. This is some text. This is some text.";
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
myTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
myTextPaint.setColor(0xFF000000);
int width = 200;
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = 0;
boolean includePadding = false;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, width, alignment, spacingMultiplier, spacingAddition, includePadding);
float height = myStaticLayout.getHeight();
以上逗柴。
感謝:
1.stackoverflow - How is StaticLayout used in Android?
2.Android - drawing multiline text on bitmap
3.Usability of BoringLayout