1. 程式人生 > >Android TextView自適應文字大小

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相對