問題
我們還是從問題開始說起矿微,在開發(fā)中我們經(jīng)常會(huì)用到TextView顯示文本座慰,并根據(jù)產(chǎn)品要求顯示為單行或者是規(guī)定的幾行仑氛,超出部分顯示為省略號(hào)的需求坝疼。最近在做這個(gè)需求的時(shí)候搜贤,發(fā)現(xiàn)了一些問題,在這里記錄一下钝凶。
實(shí)現(xiàn)
在這個(gè)需求上仪芒,我們一般都是這樣寫:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true" />
但是這樣編譯器會(huì)有一個(gè)這樣的提示:
由于google給的提示,我們會(huì)欣然接受,將singleLine改為了maxLines="1"掂名,那么問題就出現(xiàn)了据沈。
效果
通過maxLines="1"設(shè)置后,顯示在手機(jī)上的文案就會(huì)發(fā)現(xiàn)顯示不完全的問題饺蔑,例如:hello world锌介!
可能只顯示了hello world或者h(yuǎn)ello,而省略號(hào)完全沒有猾警,再例如:“你好世界”可能顯示為“你好世”孔祸,而在我的項(xiàng)目里有過這樣的情況,就是“(你好发皿,世界)”崔慧,最后面的一半括號(hào)沒了,顯示為“(你好雳窟,世界”尊浪。
原因
問題說完了,看一下是什么導(dǎo)致的封救。
maxLines:對(duì)行的高度進(jìn)行限制拇涤,并不會(huì)影響顯示的換行規(guī)則,顯示不完則不顯示
singleLine:限制在一行顯示誉结,如果顯示不完則會(huì)顯示省略號(hào)
如果將省略號(hào)設(shè)置在中間位置鹅士,則maxLines無效。
TextView內(nèi)部輔助類:
1惩坑、BoringLayout 主要負(fù)責(zé)顯示單行文本掉盅,并提供了isBoring方法來判斷是否滿足單行文本的條件。
2以舒、DynamicLayout當(dāng)文本為Spannable的時(shí)候趾痘,TextView就會(huì)使用它來負(fù)責(zé)文本的顯示,在內(nèi)部設(shè)置了SpanWatcher蔓钟,當(dāng)檢測(cè)到span改變的時(shí)候永票,會(huì)進(jìn)行reflow,重新計(jì)算布局滥沫。
3侣集、StaticLayout當(dāng)文本為非單行文本,且非Spannable的時(shí)候兰绣,就會(huì)使用StaticLayout世分,內(nèi)部并不會(huì)監(jiān)聽span的變化,因此效率上會(huì)比DynamicLayout高缀辩,只需一次布局的創(chuàng)建即可臭埋,但其實(shí)內(nèi)部也能顯示SpannableString踪央,只是不能在span變化之后重新進(jìn)行布局而已。
TextView的折行包含以下規(guī)律:
1斋泄、半角字符與全角字符混亂所致:這種情況一般就是漢字與數(shù)字杯瞻、英文字母混用。
2炫掐、TextView在顯示中文的時(shí)候標(biāo)點(diǎn)符號(hào)不能顯示在一行的行首和行尾魁莉,如果一個(gè)標(biāo)點(diǎn)符號(hào)剛好在一行的行尾,該標(biāo)點(diǎn)符號(hào)就會(huì)連同前一個(gè)字符跳到下一行顯示募胃。
3旗唁、一個(gè)英文單詞不能被顯示在兩行中( TextView在顯示英文時(shí),標(biāo)點(diǎn)符號(hào)是可以放在行尾的痹束,但英文單詞也不能分開 )检疫。
StaticLayout中針對(duì)ellipsize屬性,對(duì)文本內(nèi)容單獨(dú)進(jìn)行了處理(之前的折行處理效果在這里就不管用了)祷嘶,然后Layout.onDraw的時(shí)候只會(huì)繪制處理完后的text屎媳。
建議
如果為了實(shí)現(xiàn)顯示省略號(hào)的效果,建議使用singleLine论巍。
如果單獨(dú)是為了限制行數(shù)烛谊,建議使用maxLines
延伸
實(shí)現(xiàn)省略號(hào)的效果時(shí),如果要求顯示超過幾個(gè)字符后嘉汰,顯示省略號(hào)丹禀,可以在代碼中進(jìn)行設(shè)置:
String string = "hello world!";
if(string.length() > index) {
String subString = string.substring(0, index);
string = subString + "…";
}
這種方式在使用android:maxLength="index"或者android:maxEms="index"效果不好的時(shí)候使用。
這個(gè)效果不好就是使用maxLength沒有省略號(hào)的效果鞋怀,使用maxEms顯示的字符數(shù)和要求的有差別双泪,具體原因具體分析。