概述
项目中遇到一个需求要求展示一个圆形进度条并在中心绘制文字。
所以怎么才能把文字绘制在圆形的最中心呢?
先来一张图(网上找的)
canvas.drawText(String text,float x,float y,Paint mTextPaint);
参数1:text 想要绘制的文本
参数2:x 文本最左边坐标
参数3:y BaseLine所在坐标
参数3:mTextPaint 画笔
所以想要将文本绘制在文本最中心需要处理一下:
假设圆的直径为circleWidth
1 宽度确定 即X坐标位置确定
获取文本的宽度有两种方式:
//方法一 getTextBounds(String text, int start, int end, Rect bounds) Rect rect = new Rect(); paint.setTextSize(rectF.width() * 5 / 12);//设置字体大小一定要在测量之前 paint.setStrokeWidth(3); paint.getTextBounds(full, 0, full.length(), rect);//full为String是要绘制的"满"字文本
//方法二 float measureText(String text) paint.setTextSize(rectF.width() * 5 / 12);//设置字体大小一定要在测量之前 paint.setStrokeWidth(3); float textShowWidth = paint.measureText(full);
但两种方法有一定区别:
getTextBounds
: 它测量的是文字的显示范围。形象点来说,你这段文字外放置一个可变的矩形,然后把矩形尽可能地缩小,一直小到这个矩形恰好紧紧包裹住文字,那么这个矩形的范围,就是这段文字的 bounds
measureText()
: 它测量的是文字绘制时所占用的宽度。一个文字在界面中,往往需要占用比他的实际显示宽度更多一点的宽度,以此来让文字和文字之间保留一些间距,不会显得过于拥挤。所以 measureText()
比 getTextBounds()
测量出的宽度要大一些。
所以我们选用measureText()方法来确定绘制文本X坐标位置:
X: circleWidth/2-textShowWidth/2
2 高度确定 即Y坐标位置确定
想要绘制出文字的中心和圆的中心对齐只需要只需要将Y坐标从圆的中心往下移动BaseLine线到文字中心线之间的距离即可。
Ascent: BaseLine线到最顶部的距离
Descent: BaseLine线到最底部的距离
Paint.FontMetrics fontMetrics = paint.getFontMetrics(); float descent = fontMetrics.descent;//descent是基于baseline下面,所以是正数 float ascent = fontMetrics.ascent;//ascent是基于baseline上面,所以是负数
所以
BaseLine线到文字中心线之间的距离:float dy = (descent - ascent) / 2 - descent;
Y坐标为: circleWidth / 2+ dy
总结: 在直径为circleWidth的圆中心位置绘制文本
canvas.drawText(text,circleWidth/2-textShowWidth/2,circleWidth/ 2+ dy,paint);
附:完整代码
xml布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.dyjf.drawview.MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="300dp" android:background="#eeeeee" android:gravity="center"> <com.dyjf.drawview.ProgressView android:id="@+id/pv" android:layout_width="80dp" android:layout_height="150dp" android:layout_marginRight="160dp" android:background="#FFA07A" /> </LinearLayout> </LinearLayout>
View类
public class ProgressView extends View { private int width; private int height; private int circleWidth;//圆环直径 public ProgressView(Context context) { super(context); } public ProgressView(Context context, AttributeSet attrs) { super(context, attrs); } public ProgressView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); //xml设置的宽度(80*3):80 是xml中80dp;3 是该手机设备的Density width = MeasureSpec.getSize(widthMeasureSpec); height = MeasureSpec.getSize(heightMeasureSpec);//xml设置的高度 circleWidth = width > height ? height : width;//根据xml文件取小的为圆直径 Log.i("ly", width + " - " + height); } String full = "满"; String buy = "抢"; @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); Paint paint = new Paint(); paint.setColor(Color.parseColor("#cccccc")); paint.setAntiAlias(true); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(circleWidth / 30); float strokeWidth = paint.getStrokeWidth(); //因为圆环有一定宽度所以预留出圆环宽度,所以从strokeWidth到circleWidth - strokeWidth RectF rectF = new RectF(strokeWidth, strokeWidth, circleWidth - strokeWidth, circleWidth - strokeWidth); canvas.drawArc(rectF, -90, 360, false, paint);//绘制底部灰色背景圆环 paint.setColor(Color.parseColor("#303F9F")); canvas.drawArc(rectF, -90, (float) (progress * 3.6), false, paint);//绘制蓝色进度条 paint.setTextSize(rectF.width() * 5 / 12);//根据圆环大小设置字体大小,可调整 paint.setStrokeWidth(3); paint.setStyle(Paint.Style.FILL); float textShowWidth = paint.measureText(full); Paint.FontMetrics fontMetrics = paint.getFontMetrics(); float dy = (fontMetrics.descent - fontMetrics.ascent) / 2 - fontMetrics.descent; if (progress == 100) { paint.setColor(Color.parseColor("#cccccc")); canvas.drawText(full, circleWidth / 2 - textShowWidth / 2, circleWidth / 2 + dy, paint); } else { paint.setColor(Color.parseColor("#303F9F")); canvas.drawText(buy, circleWidth / 2 - textShowWidth / 2, circleWidth / 2 + dy, paint); } } float progress = 50; /** * 设置进度 * * @param pro */ public void changeProgress(float pro) { progress = pro; invalidate(); } }
效果图:
最后
以上就是伶俐早晨为你收集整理的如何将自定义文本TextView绘制在其他图形中心位置的全部内容,希望文章能够帮你解决如何将自定义文本TextView绘制在其他图形中心位置所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复