自动换行的矢量文字(android demo)

由于矢量字体的宽度不同,自测android字体,发现当中文字体大小为100像素时,字母s等 宽度大概在52,字母l等 宽度大概在26,这样自动换行就不可以按字符的个数计算截取每行显示的字串。

直接上代码。支持\n换行,支持矩形内显示不下的时候,把最后显示的字符换成...

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.View;

public class MyView extends View {

    private Paint paint;

    public MyView(Context context) {
        super(context);
        paint = new Paint();
    }

    protected void onDraw(Canvas canvas) {
        String s = "kkkkkkkkkkkkkllllllllllllllll阿三空间的了看见拉是假的了解拉萨空间的路径去我而刻录机自行车刻录机是的了次幂,你,吉林省地方pitqwer 省电费撒在西昌采访";

        int x = 50, y = 50, w = 400, h = 100;
        int textSize = 30;
        paint.setColor(0xff00ff00);

        canvas.drawRect(x, y, x + w, y + h, paint);

        long time = System.currentTimeMillis();
        drawString2(canvas, s, x, y, w, h, textSize, 0xff000000);
        System.out.println("use time " + (System.currentTimeMillis() - time));
    }

    /**
     * @param canvas
     * @param text
     * @param x
     *            矩形x
     * @param y
     *            矩形y
     * @param w
     *            矩形宽
     * @param h
     *            矩形高
     * @param textSize
     *            文字大小(像素)
     * @param color
     *            文字颜色(argb)
     */
    public void drawString2(Canvas canvas, String text, int x, int y, int w,
            int h, int textSize, int color) {
        paint.setTextSize(textSize);
        paint.setColor(color);

        StringBuffer sb = new StringBuffer();
        int maxLine = h / textSize;
        int curLine = 0;
        for (int i = 0; i < text.length(); i++) {
            char tmp = text.charAt(i);
            sb.append(tmp);
            if (tmp == '\n') {
                curLine++;
                canvas.drawText(sb.toString(), x, y + curLine * textSize, paint);
                sb = new StringBuffer();
            } else if (paint.measureText(sb.toString())
                    + getFontW(text.charAt(i == text.length() - 1 ? i : i + 1)) >= w) {
                curLine++;
                if (curLine == maxLine && i != text.length() - 1) {
                    sb.replace(sb.length() - 3, sb.length(), "...");
                    System.out.println("draw time++");
                    canvas.drawText(sb.toString(), x, y + curLine * textSize,
                            paint);
                    break;
                }
                System.out.println("line:" + curLine + " all:"
                        + getFontW(sb.toString()) + " me:"
                        + paint.measureText(sb.toString()));
                System.out.println("draw time++");
                canvas.drawText(sb.toString(), x, y + curLine * textSize, paint);
                sb = new StringBuffer();
            } else if (i == text.length() - 1) {
                System.out.println("draw time++");
                canvas.drawText(sb.toString(), x, y + (curLine + 1) * textSize,
                        paint);
            }
        }
    }

    private float getFontW(char c) {
        float[] widths = new float[1];
        paint.getTextWidths(String.valueOf(c), widths);
        return widths[0];
    }

    private float getFontW(String s) {
        float[] widths = new float[s.length()];
        paint.getTextWidths(s, widths);
        float sum = 0;
        for (int i = 0; i < widths.length; i++) {
            sum += widths[i];
        }
        return sum;
    }

}

运行效果:

 

方法可能还不是很完善,比如字体过大的时候,行尾可能会出现部分空白区域,比如字体大小为50,行尾由于不够绘制下一个文字,空出1~49像素的空白。

效率也应该还可以优化。

整理出来供新手学习,也希望各位能指点指点。

posted @ 2013-09-18 11:46  带狗狗带  Views(479)  Comments(0Edit  收藏  举报