前言:有經驗的android開發者,應該都會遇到在自定義view的時候,在view的某個地方寫文字,那麼當你在自定義的view中寫文字的時候,能夠做到定點寫文字嗎?能夠指哪寫哪嗎?寫出來的文字的位置和自己想要的位置一樣嗎?即使你最後寫的文字的位置和自己想象的位置是一樣的,那麼你知道其中的原理嗎?如果其中有乙個你不能回答出來,那就認真的閱讀本文吧!本文會給出你想要的答案...看下下面的圖,假如下面的圖是我們要做出的效果
很簡單,有沒有?就是在乙個圓的中心寫文字。紅色的圓形很好畫出來,那麼我們怎麼將文字寫在圓的中心點上呢?第一時間想到的是拿到圓中心點的座標,然後直接呼叫drawtext()
方法來寫文字。實現的**大致如下
@override
protected
void
ondraw
(canvas canvas)
複製**
現在,看下上面**實現的效果
上圖中的黃線是在圓的中心點畫的線,可以發現上面**實現的效果,明顯不是我們想要的效果,為什麼會這樣呢?下文會給出答案。
在android中自定義view的時候,怎麼讓系統知道應該在**畫出我們想要的圖形呢?比如畫上面的圓,這時我們就要告訴系統,我們要畫的圓形的圓心在什麼位置,告訴系統我們想要的圓的半徑是多少,然後系統就能在合適的位置畫出你想要的圓了。同樣,在畫文字的時候我們要指定文字在什麼位置,而指定的座標的位置就是文字的基線。
要理解drawtext()
中的基線是什麼,需要先了解一下darwtext()
方法,darwtext()
方法有四個引數,如下
drawtext(@nonnull string text, float x, float y, @nonnull paint paint)
複製**
第乙個引數為你想要寫的內容,第二個引數為文字開始的x軸座標,第三個引數為文字開始的y軸座標,第四個引數為畫筆。以第二個第三個引數畫的一條水平線,就是drawtext()
的基線。如上文中的第二張圖,黃色的線即為drawtext()
基線,
注:第二和第三個引數不一定為文字開始的座標,也可能為文字中心的座標或則文字結尾的座標,具體是哪種座標與paint
中的settextalign()
方法有關。
可以得出結論,只要確定了基線的位置就確定了要畫的文字的位置了。那麼給定乙個座標,怎麼確定基線的位置呢?其實畫文字的時候,除了基線以外,還有其他幾條線,其他幾條線的位置如下圖
這幾條線的意義分別是:
這幾條線的位置可以通過fontmetrics
物件獲得。
描述給定文字的各種度量值的類,它有五個成員變數,分別為top
、ascent
、descent
、bottom
、leading
。這幾個成員變數的值都是相對基線位置的距離,如:
fontmetrics.top = top的y座標 - 基線
想要獲取fontmetrics,可以通過getfontmetrics()
方法獲取,具體**如下
paint mpaint = new paint()
mpaint.settextsize(getresources().getdimensionpixelsize(r.dimen.sp18));
mpaint.setcolor(color.white);
mpaint.settextalign(paint.align.center);
mpaint.setstrokewidth(1);
paint.fontmetrics fontmetrics = mpaint.getfontmetrics();
複製**
使用fontmetrics獲取到的top
、ascent
、descent
、bottom
、leading
成員變數的值,是相對於基線的距離,並不是座標,可以看下下圖,方便理解
可以發現top
、ascent
的值為負數,descent
、bottom
的值為正數,為什麼會這樣呢?因為top
線和ascent線在基線的上方,fontmetrics
物件中的幾個成員變數的值都是表示相對基線的位置。
了解了fontmetrics
再結合下圖
可以得到下面的公式:
根據得出的公式可以計算出基線的y座標
top的y座標 = 基線 + fontmetrics.top實現的**如下基線 = top的y座標 - fontmetrics.top
paint mpaint = new paint();
mpaint.settextsize(getresources().getdimensionpixelsize(r.dimen.sp18));
mpaint.setstrokewidth(1);
mpaint.setcolor(color.red);
paint.fontmetrics fontmetrics = mpaint.getfontmetrics();
float baseline = cy-fontmetrics.top;//cy指定點的y座標
canvas.drawtext("wizardev", 0, baseline, mpaint);
複製**
給定中間線寫文字,可以說是自定義view寫文字時用的最多的了,如,將文字寫在圓的正中間,如上圖,圓的中心線將文字平分,這種就是本文說的給定中間線寫文字。文章前面說了,只要確定了基線的位置,文字的位置也就確定了,那麼像這種,怎樣來確定基線的位置呢?這時我們可以借助其他的幾條線來計算出基線的位置。
如上圖,將top
和center
之間的間距設為a
,將center
和baseline
之間的距離設為b
,將center
和bottom
之間的距離設為c
。這是就可以得出下面的公式
a = c = (bottom - top)/2然後根據上文得到的公式:b = baseline - center
b = c - (bottom - baseline )
bottom = fontmetrics.bottom + baseline可以將最上面的公式修改為:top = fontmetrics.top + baseline
baseline - center = (fontmetrics.bottom + baseline - fontmetrics.top - baseline) / 2 - (fontmetrics.bottom + baseline - baseline)最後的到的公式為:
baseline = center - (fontmetrics.bottom - fontmetrics.top) / 2 + fontmetrics.bottom上面的到的公式就是給出中心線的位置,最後計算出的基線所在位置的公式。
這種情況應該是最簡單的了,直接把給定點的y座標作為基線的y座標就行了。
Android自定義控制項之自定義View 二
效果如下圖 1 自定義ringview繼承view新增其構造方法並建立畫筆 public class ringview extends view protected boolean isrunning false public ringview context context public ring...
Android自定義View 自定義元件
自繪控制項也分兩種,自定義元件和自定義容器,自定義元件是繼承view類,自定義容器時繼承viewgrounp 今天主要分析下自定義元件 還是舉個例子來的實際些,假如我們要畫乙個最簡單的textview,首先想到的就是canvas.drawtext 方法,怎麼畫了?還是得一步一步來 1 寫乙個myte...
Android自定義View實現
android自定義view實現很簡單 繼承view或者其子類,重寫建構函式 ondraw,onmeasure 等函式,根據繼承的類的不同可能有所不同。如果自定義的view需要有自定義的屬性,需要在values下建立attrs.xml。在其中定義你的屬性。在使用到自定義view的xml布局檔案中需要...