關(guān)于TextView上標(biāo)問題

五一假期結(jié)束了悔叽。新的一周開始了莱衩,繼續(xù)奮斗!
吐槽一下前幾天被人忽視了骄蝇,心里小小的不爽了一下膳殷。算了,就不跟那些人一般見識了九火,阿Q精神還是要的赚窃。

開始今天的記錄

已經(jīng)上線運(yùn)行的項目,突然加介紹人英文資料的時候岔激,想要文字出現(xiàn)上角標(biāo)勒极,但是沒有效果。想一想虑鼎,簡單嗎辱匿?可以用富文本嗎!說干就干炫彩,何止是上標(biāo)匾七,下標(biāo)也一樣可以加上。

span.setSpan(new SuperscriptSpan(), 31, 33, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);   //上標(biāo)     
span.setSpan(new SubscriptSpan(), 33, 35, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);     //下標(biāo)     
text.append(span);  

so easy!
但是=ぁW蛞洹!
但是I荚省R靥!
加入一段文字不知道在什么地方會需要上標(biāo)呢叔磷?比如1st拢驾。
參考:https://blog.csdn.net/zhangxiangliang2/article/details/73658011

首先是獲取到需要上標(biāo)的位置

當(dāng)然是用到用到一個正則表達(dá)式:(?<=\b\d{1,10})(st|nd|rd|th)(?=\b)
這個正則表達(dá)式分為三個部分:
(?<=\b\d{1,10})
(st|nd|rd|th)
(?=\b)
第一部分是后行斷言(lookbehind),用來匹配我們希望展示內(nèi)容之前的指定模式。后行斷言用?<=表示改基,后面跟著我們希望匹配的模式繁疤。

此處\b\d{1,10}要么匹配一個空格或者是一個字符串的開始(\b代表);然后后面跟1到10的數(shù)字(\d{1,10}代表)。

在java中不可能用通配符匹配后行斷言嵌洼,因為假如編譯器無法確定后行斷言的最大長度正則編輯會失敗案疲,這就是我為什么在這里指定了一個范圍,而不是使用\d+麻养。

第二部分是我們真正要展示的內(nèi)容。正如我們想要展示的序數(shù)后綴诺舔,我們使用(st|nd|rd|th)鳖昌。

第三部分是先行斷言(lookahead),用來匹配我們希望展示內(nèi)容之后的指定模式。后行斷言用?=表示低飒,后面跟著我們希望匹配的模式许昨。

此處\b要么匹配一個空格要么匹配一個字符串的結(jié)尾(\b代表)。

認(rèn)真的你可能會想到一個問題褥赊,為什么我們不只用第二個部分就可以了呢?

因為這樣我們會在“first”上匹配"st"成first,很明顯這不是我們想要的糕档。

正確使用先行斷言與后行斷言才能達(dá)到我們的目的,最后我們要匹配如下的模式:

<whitespace or start><one or more digits>st|nd|rd|th<whitespace or end>

其次是用富文本設(shè)置成上標(biāo)
SuperscriptSpan superscript = new SuperscriptSpan();
RelativeSizeSpan size = new RelativeSizeSpan(PROPORTION);
stringBuilder.setSpan(superscript, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
stringBuilder.setSpan(size, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

其中使用SuperscriptSpan來升高文字基準(zhǔn)線拌喉,RelativeSizeSpan來改變TextView文字大小速那。

封裝好的工具類

public class OrdinalSuperscriptFormatter {
    private static final String SUPERSCRIPT_REGEX = "(?<=\\b\\d{0,10})(st|nd|rd|th)(?=\\b)";
    private static final Pattern PATTERN = Pattern.compile(SUPERSCRIPT_REGEX);
    private static final float PROPORTION = 0.5f;
 
    private final SpannableStringBuilder stringBuilder;
 
    public OrdinalSuperscriptFormatter(@NonNull SpannableStringBuilder stringBuilder) {
        this.stringBuilder = stringBuilder;
    }
 //執(zhí)行正則表達(dá)式的邏輯
    public void format(TextView textView) {
        CharSequence text = textView.getText();
        Matcher matcher = PATTERN.matcher(text);
        stringBuilder.clear();
        stringBuilder.append(text);
        while (matcher.find()) {
            int start = matcher.start();
            int end = matcher.end();
            createSuperscriptSpan(start, end);
        }
        textView.setText(stringBuilder);
    }
 
    private void createSuperscriptSpan(int start, int end) {
        SuperscriptSpan superscript = new SuperscriptSpan();
        RelativeSizeSpan size = new RelativeSizeSpan(PROPORTION);
        stringBuilder.setSpan(superscript, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
        stringBuilder.setSpan(size, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
    }
}

使用

 TextView textView = (TextView) findViewById(R.id.text_view);
 OrdinalSuperscriptFormatter formatter = new OrdinalSuperscriptFormatter(new SpannableStringBuilder());
 formatter.format(textView);
效果如下
上標(biāo)圖片效果圖.png

附上TextView高級用法使用TextView實現(xiàn)更多效果

以上使用還是會出現(xiàn)一些問題,比如我就想顯示1 th尿背,不想弄成1 th端仰,由于上邊的斷言種\b包含了空格,所以需要處理空格的問題田藐。
所以最后修改為 \S(?<=\b\d{0,10})(st|nd|rd|th)(?=\b) 不過一般情況下不會出現(xiàn)這種情況荔烧,用上邊的就ok了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末汽久,一起剝皮案震驚了整個濱河市鹤竭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌景醇,老刑警劉巖臀稚,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異啡直,居然都是意外死亡烁涌,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進(jìn)店門酒觅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來撮执,“玉大人,你說我怎么就攤上這事舷丹∈闱” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長谋币。 經(jīng)常有香客問我仗扬,道長,這世上最難降的妖魔是什么蕾额? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任早芭,我火速辦了婚禮,結(jié)果婚禮上诅蝶,老公的妹妹穿的比我還像新娘退个。我一直安慰自己,他們只是感情好调炬,可當(dāng)我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布语盈。 她就那樣靜靜地躺著,像睡著了一般缰泡。 火紅的嫁衣襯著肌膚如雪刀荒。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天棘钞,我揣著相機(jī)與錄音缠借,去河邊找鬼。 笑死武翎,一個胖子當(dāng)著我的面吹牛烈炭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宝恶,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼符隙,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了垫毙?” 一聲冷哼從身側(cè)響起霹疫,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎综芥,沒想到半個月后丽蝎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡膀藐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年屠阻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片额各。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡国觉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出虾啦,到底是詐尸還是另有隱情麻诀,我是刑警寧澤痕寓,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站蝇闭,受9級特大地震影響呻率,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜呻引,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一礼仗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧逻悠,春花似錦藐守、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乾蓬。三九已至惠啄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間任内,已是汗流浹背撵渡。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留死嗦,地道東北人趋距。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像越除,于是被迫代替她去往敵國和親节腐。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 專業(yè)考題類型管理運(yùn)行工作負(fù)責(zé)人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,977評論 0 13
  • 《裕語言》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 26,010評論 5 19
  • ¥開啟¥ 【iAPP實現(xiàn)進(jìn)入界面執(zhí)行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程摘盆,因...
    小菜c閱讀 6,358評論 0 17
  • 《ilua》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 1...
    葉染柒丶閱讀 10,533評論 0 11
  • 昨天是星期日翼雀,下午沒課。一(1)班班主任有急事去醫(yī)院了孩擂,我馬上過去代課狼渊。 我從早讀跟到上午第二節(jié),誰的拉鏈沒拉好类垦,...
    勱嘯閱讀 416評論 1 2