Android TextView自适应文字大小

如何在指定的矩形框内,显示TextView 文字不会被切割,也不用指定TextView大小(指定矩形框,不指定文字大小)

有两种方式,一种是使用Matrix做 矩阵变换,一种是用StaticLayout进行遍历来选取合适的TextSize

Matrix:

    public void drawText(String text, Paint paint, Canvas canvas, MyItem item) {
        Rect textBound = new Rect();
        paint.getTextBounds(text, 0,
                text.length(), textBound);
        float descent = paint.descent();
        int height = textBound.height();
        int width = textBound.width();
        float[] startPoints = {
                0, -height + descent,
                width, -height + descent,
                width, descent,
                0, descent
        };

        float[] endPoints = {
                item.leftTopPoint.x, item.leftTopPoint.y,
                item.rightTopPoint.x, item.rightTopPoint.y,
                item.rightBottomPoint.x, item.rightBottomPoint.y,
                item.leftBottomPoint.x, item.leftBottomPoint.y
        };

        Matrix fontMatrix = new Matrix();
        fontMatrix.setPolyToPoly(startPoints, 0, endPoints, 0, 4);

        paint.setColor(item.getTextColor());
        final int saveCount = canvas.save();
        canvas.concat(fontMatrix);
        canvas.drawText(text, 0, 0, paint);

        canvas.restoreToCount(saveCount);
    }

  • MyItem是我的自定义类,需要替换成你自己的。
  • endPoints数组中四个点,分别是矩形的 左上、右上、右下、左下 点的 x,y坐标

主要采用的是Matrix的PolyToPoly方法,就是给定 原坐标点、目的坐标点,生成变换的Matrix

优点:

   绘制矩形框 不是长方形,是梯形 也可以完美的贴上去

缺点:

    文字会模糊,失去锐度


StaticLayout

 private void drawStatic(Paint paint, Canvas canvas, TextPaint textPaint,
                            int drawWidth, int drawHeight, int drawLeft, int drawTop) {
        int textHeight = initConfig(getText(), textPaint, drawWidth, drawHeight, DEFAULT_TEXT_SIZE);
        if (textHeight == -1) {
            return;
        }

        StaticLayout layout = new StaticLayout(getText(), textPaint, drawWidth, Layout.Alignment.ALIGN_NORMAL, mSpacingMulti, mSpacingAdd, true);
        layout.draw(canvas);
    }


    /**
     * 设置paint的textSize
     */
    int initConfig(CharSequence text, TextPaint textPaint, int viewWidth, int viewHeight, float defaultTextSize) {
        // Do not resize if the view does not have dimensions or there is no text
        if (text == null || text.length() == 0 || viewHeight <= 0 || viewWidth <= 0 || defaultTextSize == 0) {
            return -1;
        }

        float targetTextSize = defaultTextSize;
        int textHeight = getStaticLayoutHeight(text, textPaint, viewWidth, targetTextSize);

        while (textHeight > viewHeight) {
            targetTextSize = targetTextSize - 2;
            textHeight = getStaticLayoutHeight(text, textPaint, viewWidth, targetTextSize);
        }

        float preTextSize = targetTextSize;
        while (textHeight < viewHeight) {
            preTextSize = targetTextSize;
            targetTextSize += 2;
            textHeight = getStaticLayoutHeight(text, textPaint, viewWidth, targetTextSize);
        }
        textPaint.setTextSize(preTextSize);
        return textHeight;
    }

    int getStaticLayoutHeight(CharSequence source, TextPaint paint, int width, float textSize) {
        paint.setTextSize(textSize);
        StaticLayout layout = new StaticLayout(source, paint, width, Layout.Alignment.ALIGN_NORMAL, mSpacingMulti, mSpacingAdd, true);
        return layout.getHeight();
    }

  • StaticLayout也是TextView中负责 text 分行、测量字体库宽度的类
  • 就是采用遍历的方法来确定文字大小
  • 初始的文字大小,设置成矩形的高就行,这样接近点

优缺点与Matrix相对






你可能感兴趣的:(Android)