package com.lfk.justwetools.View.VerText;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
/**
* Created by liufengkai on 15/10/3.
*/
public class VerTextView extends View {
// 绘制方向
public final int RIGHT = 1;
public static final int LEFT = 0;
// 绘制的最大长度
public int MaxInOneLine = 0;
// 绘制文字画笔
private Paint paint;
// 绘制下划线画笔
private Paint mPaint;
// 绘制下划线的路径
private Path mPath;
// 绘制的x,y 位置
private int mTextPosX = 0;
private int mTextPosY = 0;
// 绘制宽度
private int mTextWidth = 0;
// 绘制高度
private int mTextHeight = 0;
// 绘制字体高度
private int mFontHeight = 0;
// 字体大小
private float mFontSize = 40;
// 传入的文本
private String text = "";
// 字符串真实的行数
private int mLineSize = 0;
// 列宽度
private int mLineWidth = 0;
// 不包含下划线的列宽度
private int mLineWidthWithoutUnderLine = 0;
// 列间距
private int mLineSpacing = 20;
// 字符串长度
private int TextLength = 0;
// 每行超过字数自动换行数
private static int maxCountInOneLine = 18;
// 存储上次的width
private int oldwidth = 0;
// 绘制字体的默认方向
private Paint.Align textStartAlign = Paint.Align.RIGHT;
// 是否开启下划线
private boolean IsOpenUnderLine = false;
// 下划线的宽度
private int underLineWidth = 5;
// 下划线的颜色
private int underLineColor = Color.BLACK;
// 下划线的间距
private int underLineSpacing = 10;
// 传入用于处理事件的Handler
private Handler mHandler = null;
// 获取的背景
private BitmapDrawable drawable = (BitmapDrawable) getBackground();
public VerTextView(Context context) {
super(context);
paint = new Paint();
paint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/fun_font.TTF"));
// 文字居中
paint.setTextAlign(Paint.Align.CENTER);
// 平滑处理
paint.setAntiAlias(true);
// 默认文字颜色
paint.setColor(Color.BLACK);
if (IsOpenUnderLine) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(underLineColor);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(underLineWidth);
}
mFontSize = 40;
}
public VerTextView(Context context, AttributeSet attrs) {
super(context, attrs);
paint = new Paint();
paint.setTypeface(Typeface.createFromAsset(context.getAssets(), "fonts/fun_font.TTF"));
// 文字居中
paint.setTextAlign(Paint.Align.CENTER);
// 平滑处理
paint.setAntiAlias(true);
// 默认文字颜色
paint.setColor(Color.BLACK);
if (IsOpenUnderLine) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(underLineColor);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(underLineWidth);
}
try {
mFontSize = Float.parseFloat(attrs.getAttributeValue(null, "textSize"));
} catch (Exception e) {
Log.e("get font size", "error");
mFontSize = 40;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// if (drawable != null) {
// // 画背景
// Bitmap b = Bitmap.createBitmap(drawable.getBitmap(), 0, 0, mTextWidth, mTextHeight);
// canvas.drawBitmap(b, new Matrix(), paint);
// }
// 画字
draw(canvas, this.text);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredHeight = measureHeight(heightMeasureSpec);
if (mTextWidth == 0) getTextSize();
Log.e("measuredHeight", measuredHeight + "");
setMeasuredDimension(mTextWidth, Math.min(measuredHeight, MaxInOneLine));
// if (oldwidth != getWidth()) {
// oldwidth = getWidth();
// if (mHandler != null) mHandler.sendEmptyMessage(LAYOUT_CHANGED);
// }
}
/**
* 绘制
*
* @param canvas
* @param text
*/
private void draw(Canvas canvas, String text) {
if (IsOpenUnderLine) {
mPath = new Path();
mPaint = new Paint();
mPaint.setColor(underLineColor);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(underLineWidth);
}
char StringItem;
mTextPosY = 0;
mTextPosX = textStartAlign == Paint.Align.LEFT ? mLineWidth : mTextWidth - mLineWidth;
for (int i = 0; i < this.TextLength; i++) {
StringItem = text.charAt(i);
if (StringItem == '\n') {
// 换行
if (IsOpenUnderLine)
drawUnderLine(canvas);
if (textStartAlign == Paint.Align.LEFT) {
mTextPosX += mLineWidth;
} else {
mTextPosX -= mLineWidth;
}
mTextPosY = 0;
} else {
mTextPosY += mFontHeight;
if (mTextPosY > this.mTextHeight) {
if (IsOpenUnderLine)
drawUnderLine(canvas);
if (textStartAlign == Paint.Align.LEFT) {
mTextPosX += mLineWidth;
} else {
mTextPosX -= mLineWidth;
}
i--;
mTextPosY = 0;
} else {
canvas.drawText(String.valueOf(StringItem), mTextPosX, mTextPosY, paint);
if (i == this.TextLength - 1) {
if (IsOpenUnderLine)
drawUnderLine(canvas);
}
}
}
}
}
/**
* 绘制下划线
*
* @param canvas
*/
private void drawUnderLine(Canvas canvas) {
mPath.moveTo(mTextPosX - mLineWidthWithoutUnderLine / 2 - underLineSpacing, 0);
mPath.lineTo(mTextPosX - mLineWidthWithoutUnderLine / 2 - underLineSpacing, mTextPosY);
canvas.drawPath(mPath, mPaint);
mPath.reset();
}
/**
* 计算控件的高度
*
* @param measureSpec
* @return
*/
private int measureHeight(int measureSpec) {
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
float[] widths = new float[1];
// 获取单个汉字的宽度
paint.getTextWidths("蛤", widths);
int result = (int) widths[0] * maxCountInOneLine;
if (specMode == MeasureSpec.EXACTLY) {
result = specSize;
} else {
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
// 设置文本高度
mTextHeight = result;
// mTextHeight = (int)widths[0] * maxCountInOneLine;
return result;
}
public void setText(String text) {
this.text = text;
this.TextLength = text.length();
// 重新调整位置
if (mTextHeight > 0) getTextSize();
}
/**
* 计算文字行数和总宽
*/
private void getTextSize() {
char StringItem;
// 每行的字符数所对应的长度
int SizeInOneLine = 0;
paint.setTextSize(mFontSize);
// 获得字宽
if (mLineWidth == 0) {
float[] widths = new float[1];
// 获取单个汉字的宽度
paint.getTextWidths("蛤", widths);
// 计算列宽度
// mLineWidth = (int) Math.ceil(widths[0] * 1.2 + 2);
mLineWidth = mLineSpacing + (int) widths[0];
if (IsOpenUnderLine) {
mLineWidthWithoutUnderLine = mLineWidth;
mLineWidth += underLineWidth + underLineSpacing;
}
}
Paint.FontMetrics fm = paint.getFontMetrics();
// 获得字体高度
mFontHeight = (int) (Math.ceil(fm.descent - fm.top) * 0.9);
// 计算文字行数
mLineSize = 0;
MaxInOneLine = 0;
for (int i = 0; i < this.TextLength; i++) {
StringItem = this.text.charAt(i);
if (StringItem == '\n') {
// 行数加一
mLineSize++;
SizeInOneLine = 0;
} else {
SizeInOneLine += mFontHeight;
// 如果某一行的字符总长超过了之前获取的长度,就会换行
if (SizeInOneLine > this.mTextHeight) {
mLineSize++;
// 重新读入这个字符,由于h被清空会在下一行进行绘制
i--;
SizeInOneLine = 0;
} else {
if (SizeInOneLine > MaxInOneLine) {
MaxInOneLine = SizeInOneLine;
}
// 最后一个字符结束再加入一行,否则最后一行显示不全
if (i == this.TextLength - 1) {
mLineSize++;
}
}
}
}
mLineSize++;
// 计算文字总宽度
mTextWidth = mLineWidth * mLineSize;
// 重新调整大小
measure(mTextWidth, getHeight());
// 重新绘制容器位置
layout(getRight() - mTextWidth, getTop(), getRight(), getBottom());
}
public void setFontSize(float mFontSize) {
if (mFontSize != paint.getTextSize()) {
this.mFontSize = mFontSize;
if (mTextHeight > 0) getTextSize();
}
}
public void setmHandler(Handler mHandler) {
this.mHandler = mHandler;
}
/**
* 设定与下划线的间距
*
* @param mLineSpacing
*/
public void setmLineSpacing(int mLineSpacing) {
this.mLineSpacing = mLineSpacing;
}
/**
* 设定一行的最大字数
*
* @param maxCountInOneLine
*/
public static void setMaxCountInOneLine(int maxCountInOneLine) {
VerTextView.maxCountInOneLine = maxCountInOneLine;
}
/**
* 设定文字的起始方向
*
* @param leftOrRight
*/
public void setTextStartAlign(int leftOrRight) {
switch (leftOrRight) {
case RIGHT:
textStartAlign = Paint.Align.RIGHT;
break;
case LEFT:
textStartAlign = Paint.Align.LEFT;
break;
}
}
/**
* 文本颜色
*
* @param color
*/
public void setTextColor(int color) {
paint.setColor(color);
}
/**
* 下划线开关
*
* @param isOpenUnderLine
*/
public void setIsOpenUnderLine(boolean isOpenUnderLine) {
IsOpenUnderLine = isOpenUnderLine;
}
/**
* 下划线宽度
*
* @param underLineWidth
*/
public void setUnderLineWidth(int underLineWidth) {
this.underLineWidth = underLineWidth;
}
/**
* 下划线颜色
*
* @param underLineColor
*/
public void setUnderLineColor(int underLineColor) {
this.underLineColor = underLineColor;
}
/**
* 下划线间距
*
* @param underLineSpacing
*/
public void setUnderLineSpacing(int underLineSpacing) {
this.underLineSpacing = underLineSpacing;
}
}