處理字符串的長度和寬度,並無想象中的那麼簡單,要講字符串畫到自定義view的中心點,更加沒有那麼簡單!算法
介紹兩種計算方法,可是結果卻很意外哦!canvas
(1)最小外接矩形
ide
paint.setTextSize(textSize);
paint.setTypeface(Typeface.MONOSPACE);
Rect r = new Rect();
paint.getTextBounds(text,0,text.length(),r);
int height = r.bottom - r.top;
int width = r.right - r.left;this
(2)使用FontMetricsspa
Paint.FontMetrics fm = paint.getFontMetrics(); float textWidth = paint.measureText(text); float textHeight = fm.bottom - fm.top;
說明:這兩種方法計算方法結果會有很大的出入,緣由是什麼呢?據我猜想啊...第一種方法是計算字符串所佔的最小大小,也就是包圍字符串的最小外接矩形(能夠算出字符串的實際長度和寬度);而第二種則是老外針對他們的字母的計算,看看字母a,b,j這些要怎麼計算它的高度?難道a,b,j都要有一個計算其高度的算法?不可能啊,顯示出來也不美觀,最起碼得按字母j計算,補上a和b缺乏的部分,讓全部的字母都是一個高度,老外就想了個轍,把字母的整個高度分紅好幾個部分(想一想小學寫拼音的),你想要什麼本身處理去,好比:descent,ascent,top,bottom以及leading,這些東西都封裝在FontMetrics類裏面。下面是兩種種算法的示意圖。code
自定義一個圓圈字符串
Circle View { private String text = "帥"; private int textColor = Color.BLACK; private int textSize = 0; private PointF center = new PointF(0.0f, 0.0f); private float strokeWidth = 0.0f; private float radius = 0.0f; private int fillColor = Color.RED; private int strokeColor = Color.GREEN; private Paint paint; public Circle(Context context) { this(context, null); } public Circle(Context context, AttributeSet attrs) { this(context, attrs, 0); } public Circle(Context context, AttributeSet attrs, defStyleAttr) { super(context, attrs, defStyleAttr); TypedArray ta = context.obtainStyledAttributes(attrs,R.styleable.Circle); int count = ta.getIndexCount(); for(int i=0; i<count; i++) { int attr = ta.getIndex(i); switch(attr) { case R.styleable.Circle_text: text = ta.getString(attr); break; case R.styleable.Circle_textSize: textSize = (int)ta.getDimension(attr,0.0f); break; case R.styleable.Circle_textColor: textColor = ta.getColor(attr, Color.BLACK); break; case R.styleable.Circle_radius: radius = ta.getDimension(attr, 0.0f); break; case R.styleable.Circle_strokeWidth: strokeWidth = ta.getDimension(attr, 0.0f); break; case R.styleable.Circle_fillColor: fillColor = ta.getColor(attr, Color.RED); break; case R.styleable.Circle_strokeColor: strokeColor = ta.getColor(attr, 0); break; default: break; } } ta.recycle(); init(context); } private void init(Context context) { paint = new Paint(Paint.ANTI_ALIAS_FLAG); } @Override protected void onDraw(Canvas canvas) { if(radius <= 0) { return; } float cx = center.x + radius; float cy = center.y + radius; //fill paint.setColor(fillColor); paint.setStyle(Paint.Style.FILL); canvas.drawCircle(cx, cy, radius, paint); //text if(!text.isEmpty()&& textSize>0) { paint.setColor(textColor); paint.setTextSize(textSize); paint.setTypeface(Typeface.MONOSPACE); Rect r = new Rect(); paint.getTextBounds(text,0,text.length(),r); int height = r.bottom - r.top; int width = r.right - r.left; Paint.FontMetrics fm = paint.getFontMetrics(); float textWidth = paint.measureText(text); float textHeight = fm.bottom - fm.top; float offsetX = width / 2; float offsetY = height/2 - (fm.bottom - (textHeight - height)/2); canvas.drawText(text, cx-offsetX, cx+offsetY, paint); } //stroke if(strokeWidth > 0) { paint.setColor(strokeColor); paint.setStrokeWidth(strokeWidth); paint.setStyle(Paint.Style.STROKE); canvas.drawCircle(cx, cy, radius, paint); } }
上面只是部分代碼,看看onDraw方法就能夠了。可見我上面畫了一個圓圈並描邊了,而且在圓圈裏面畫了一個字符串,讓字中心居於圓心。在讓字居於圓心,但是走了一段路,請看下面圖解(看看上面代碼offsetY的獲得)。get
從上圖能夠清晰的看出,y方向應該偏移的量:offsetY = h2/2-(bh-(h1-h2)/2)。it