Android 绘制字符串到自定义view的中心
Android 绘制字符串到自定义view的中心
村上扼罢 发表于2年前
Android 绘制字符串到自定义view的中心
  • 发表于 2年前
  • 阅读 457
  • 收藏 7
  • 点赞 0
  • 评论 0

腾讯云 十分钟定制你的第一个小程序>>>   

摘要: 1. 计算字符串的长度和宽度 2. 自定义view 3. 效果

        处理字符串的长度和宽度,并没有想象中的那么简单,要讲字符串画到自定义view的中心点,更加没有那么简单!

1. 计算字符串的长度

        介绍两种计算方法,但是结果却很意外哦!

        (1)最小外接矩形      

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;

        (2)使用FontMetrics

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类里面。下面是两种种算法的示意图。


2. 自定义view

        自定义一个圆圈

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的得到)。

        从上图可以清晰的看出,y方向应该偏移的量:offsetY = h2/2-(bh-(h1-h2)/2)。

3. 效果


共有 人打赏支持
粉丝 2
博文 12
码字总数 11266
×
村上扼罢
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: