自定義View文本居中問題

文本結(jié)構(gòu)

其實(shí)是沒有文本結(jié)構(gòu)這個(gè)概念的,所謂的文本結(jié)構(gòu)篮赢,是作者定義出來的用來描述文本繪制到顯示屏的一個(gè)概念齿椅,其中包含著BaseLine、Ascent启泣、Descent涣脚、Leading。


文本.png

BaseLine也就是我們常說的基線寥茫,Ascent遣蚀、Descent、以及Leading這些都是字體設(shè)計(jì)的規(guī)范纱耻。

現(xiàn)實(shí)現(xiàn)一個(gè)計(jì)步器芭梯,效果圖如下:


計(jì)步器.png

看起來實(shí)現(xiàn)很簡單,在onDraw方法上膝迎,先勾畫出一個(gè)圓粥帚,然后在此區(qū)域上再畫出一段弧出來,最后將文本繪制上去限次。
代碼如下

 paint.setStyle(Paint.Style.STROKE);
        paint.setColor(CIRCLECOLOR);
        paint.setStrokeWidth(RING_WIDTH);
        canvas.drawCircle(getWidth()/2,getHeight()/2,RADIUS,paint);


        paint.setColor(Color.GREEN);
        paint.setStrokeCap(Paint.Cap.ROUND);
        canvas.drawArc(getWidth()/2-RADIUS,getHeight()/2-RADIUS,
                getWidth()/2+RADIUS,getHeight()/2+RADIUS,-90,225,
                false,paint);

        paint.setTextSize(140);
        paint.setStyle(Paint.Style.FILL);
        paint.setTextAlign(Paint.Align.CENTER);
        paint.getTextBounds(demoString,0,demoString.length(),bounds);
        canvas.drawText(demoString,getWidth()/2,getHeight()/2,paint);

運(yùn)行后的效果:


效果圖.png

可以發(fā)現(xiàn)芒涡,即使我們設(shè)置了Paint.Align.CENTER的屬性,雖然在水平方向上卖漫,文本是劇中的费尽,但是在豎直方向上,文本是有所偏移的羊始。
那么問題就來了旱幼,這是Bug嗎?
不是突委,因?yàn)槲覀兪前凑誂ndroid的APi寫出來的柏卤,這既不是我們的Bug也不是Google的Bug,當(dāng)然產(chǎn)品驗(yàn)收的時(shí)候冬三,會十分肯定地跟你說,你這是個(gè)Bug缘缚。

為什么說這不是Bug呢勾笆?

仔細(xì)一看,你就會發(fā)現(xiàn)桥滨,文本底部穿過圓心窝爪。


效果圖2.png

BaseLine的位置剛好是居中的,文本繪制是以BaseLine的縱坐標(biāo)開始繪制的齐媒。所以我們只需要將BaseLine的位置減去一個(gè)偏移量蒲每,就可以獲得偏移之后的BaseLine的位置,文本也就能居中了喻括。
偏移就是文本長度的一半邀杏,如何獲得?
這里有兩種方法唬血。

1淮阐、通過文本繪制區(qū)域獲取

文本在繪制過程中,本就是一塊矩形區(qū)域刁品。所以可以通過獲得文本繪制區(qū)域的top與bottom的差泣特,來得到偏移量。

Rect bounds=new Rect();//1

protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ...
       paint.getTextBounds(demoString,0,demoString.length(),bounds);
       float offest=(bounds.top + bounds.bottom)/2;
       canvas.drawText(demoString,getWidth()/2,getHeight()/2-offest,paint);
}


注釋1通過實(shí)例化一個(gè)Rect對象挑随,再通過Paint的getTextBounds方法計(jì)算獲得Rect的值状您。
但是利用Rect獲得的偏移去實(shí)現(xiàn)居中,在列表滾動的時(shí)候居中文字會出現(xiàn)跳動兜挨,因?yàn)椴煌奈谋镜腞ect是不一樣的膏孟,雖然最后都能實(shí)現(xiàn)居中,但是在產(chǎn)品看來拌汇,這是屬于不穩(wěn)定的柒桑,甚至是一個(gè)Bug。

2噪舀、利用Ascent與Descent

由于Ascent與Descent是字體級別的設(shè)置魁淳,動態(tài)的文本并不會導(dǎo)致這個(gè)兩個(gè)值變動。通過Ascent與Descent拿到的偏移与倡,是穩(wěn)定的界逛,不變的。同時(shí)纺座,它的偏移計(jì)算只計(jì)算一次就可以了息拜,并不用放到onDraw方法里,我們通過FontMetrics來獲得這些數(shù)值。

Paint.FontMetrics fontMetrics=new Paint.FontMetrics();//1
String demoString="12030步";
    {
        paint.setTextSize(200);
        paint.setTextAlign(Paint.Align.CENTER);
        paint.getFontMetrics(fontMetrics);//2
    }

protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ...
        float offest=(fontMetrics.ascent+ fontMetrics.descent)/2;
        canvas.drawText(demoString,getWidth()/2,getHeight()/2-offest,paint);
    }
}

在注釋1可以看到FontMetrics是Paint的一個(gè)靜態(tài)類少欺,在注釋2里面通過getFontMetrics計(jì)算得到FontMetrics的值喳瓣。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市赞别,隨后出現(xiàn)的幾起案子夫椭,更是在濱河造成了極大的恐慌,老刑警劉巖氯庆,帶你破解...
    沈念sama閱讀 211,743評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異扰付,居然都是意外死亡堤撵,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,296評論 3 385
  • 文/潘曉璐 我一進(jìn)店門羽莺,熙熙樓的掌柜王于貴愁眉苦臉地迎上來实昨,“玉大人,你說我怎么就攤上這事盐固』母” “怎么了?”我有些...
    開封第一講書人閱讀 157,285評論 0 348
  • 文/不壞的土叔 我叫張陵刁卜,是天一觀的道長志电。 經(jīng)常有香客問我,道長蛔趴,這世上最難降的妖魔是什么挑辆? 我笑而不...
    開封第一講書人閱讀 56,485評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮孝情,結(jié)果婚禮上鱼蝉,老公的妹妹穿的比我還像新娘。我一直安慰自己箫荡,他們只是感情好魁亦,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,581評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著羔挡,像睡著了一般洁奈。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上绞灼,一...
    開封第一講書人閱讀 49,821評論 1 290
  • 那天睬魂,我揣著相機(jī)與錄音,去河邊找鬼镀赌。 笑死氯哮,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播喉钢,決...
    沈念sama閱讀 38,960評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼姆打,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了肠虽?” 一聲冷哼從身側(cè)響起幔戏,我...
    開封第一講書人閱讀 37,719評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎税课,沒想到半個(gè)月后闲延,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,186評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡韩玩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,516評論 2 327
  • 正文 我和宋清朗相戀三年垒玲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片找颓。...
    茶點(diǎn)故事閱讀 38,650評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡合愈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出击狮,到底是詐尸還是另有隱情佛析,我是刑警寧澤,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布彪蓬,位于F島的核電站寸莫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏档冬。R本人自食惡果不足惜储狭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,936評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望捣郊。 院中可真熱鬧辽狈,春花似錦、人聲如沸呛牲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,757評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽娘扩。三九已至着茸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間琐旁,已是汗流浹背涮阔。 一陣腳步聲響...
    開封第一講書人閱讀 31,991評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留灰殴,地道東北人敬特。 一個(gè)月前我還...
    沈念sama閱讀 46,370評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親伟阔。 傳聞我的和親對象是個(gè)殘疾皇子辣之,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,527評論 2 349

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