手记

UI效果の自带行分割线的TextView

最近看了老罗的锤子便签应用,感觉很清新,打开便签第一眼感觉每行文字的行分割线很漂亮。无聊之下,做了一个下划线效果,而且还处于不断修改中


效果图如下:


代码如下:

public class UnderlinedTextView extends TextView {

/** 默认的文字行上下间隔 */

private static final int paddingTop = 20;

private static final int paddingBottom = 30;

private static final int paddingLeft = 30;

private static final int paddingRight = 30;

/** 控件的宽度与高度 */

private int mCanvasWidth;

/** 垂直偏移量 */

private int offsetY = 0;

/** 根据屏幕容量,每行内容截取的初始位置 */

private int mStartIndex = 0;

/** 文本数组 */

private ArrayList<String> dataStr = new ArrayList<String>();

/** 文本 */

private String mText;

/** 文本画笔 */

private Paint mPaint;

/** 分割线画笔 */

private Paint mLPaint;

/** 预估一行可以容纳的字符量 */

private int mEstNumber;

/** 字符串总长度 */

private int mTextLen;

/** 字体高度 */

private int mTextHeight;

public UnderlinedTextView(Context context, AttributeSet attrs) {

super(context, attrs);

init();

}

public UnderlinedTextView(Context context) {

super(context);

init();

}

private void init() {

mLPaint = new Paint();

mLPaint.setColor(Color.parseColor("#FFF1EDE4"));

mLPaint.setAntiAlias(true);

mLPaint.setDither(true);

mLPaint.setStrokeWidth(3);

}

@Override

protected void onLayout(boolean changed, int left, int top, int right,

int bottom) {

mCanvasWidth = getWidth() - paddingLeft - paddingRight;

super.onLayout(changed, left, top, right, bottom);

}

@Override

protected void onDraw(Canvas canvas) {

// TODO Auto-generated method stub

if (dataStr == null || dataStr.size() == 0) {

mText = getText().toString();

mPaint = getPaint();

mPaint.setColor(Color.parseColor("#FF62331D"));

// 以当前字体大小,衡量一个汉字的占位

float mPerCharLength = mPaint.measureText("A");

// 预估一行可显示多少个字符

mEstNumber = (int) (mCanvasWidth % mPerCharLength == 0 ? mCanvasWidth

/ mPerCharLength

: mCanvasWidth / mPerCharLength + 1);

// 文本总长度

mTextLen = mText.length();

// 字体高度

mTextHeight = getFontHeight();

offsetY = mTextHeight + paddingTop;

while (mStartIndex < mTextLen) {

getSingleLine();

}

}

if (dataStr != null) {

for (int i = 0; i < dataStr.size(); i++) {

drawLine(canvas, dataStr.get(i));

}

}

}

private void drawLine(Canvas canvas, String content) {

if (!TextUtils.isEmpty(content)) {

canvas.drawText(content, paddingLeft, offsetY, mPaint);

offsetY += paddingBottom;

canvas.drawLine(0, offsetY, mCanvasWidth, offsetY, mLPaint);

offsetY += paddingTop + mTextHeight;

}

}

/**

 * 根据预估,取出最合适的一行内容

 */

private void getSingleLine() {

// 每次文本截取的末尾位置

int mTempLength = mStartIndex + mEstNumber;

if (mTempLength > mTextLen) {

String lastContent = mText.substring(mStartIndex);

dataStr.add(lastContent);

mStartIndex = mTextLen;

return;

}

// 取出一行预估文本

String content = mText.substring(mStartIndex, mTempLength);

// 预估文本的占位空间

int length = (int) mPaint.measureText(content);

if (length > mCanvasWidth) {

// 如果预估的位置偏大,往回缩

while (length > mCanvasWidth) {

mTempLength--;

if (mTempLength > mStartIndex && mTempLength > mStartIndex) {

content = mText.substring(mStartIndex, mTempLength - 2);

length = (int) mPaint.measureText(content);

}

}

} else if (length < mCanvasWidth) {

// 如果预估的位置偏小,往外伸

while (length < mCanvasWidth) {

mTempLength++;

if (mTempLength < mTextLen && mTempLength > mStartIndex) {

// 临时保持处理结果

String mTempContent = mText.substring(mStartIndex,

mTempLength - 2);

int mTempLen = (int) mPaint.measureText(mTempContent);

// 提前预判处理后是否超出条件,如果超出,保持当前

if (mTempLen < mCanvasWidth) {

content = mTempContent;

length = mTempLen;

} else {

break;

}

}

}

}

// 保存取出的本行内容

dataStr.add(content);

// 重置初始位置

mStartIndex = mTempLength;

}

/**

 * 得到字体高度

 * 

 * @return

 */

private int getFontHeight() {

FontMetrics fm = mPaint.getFontMetrics();

return (int) Math.ceil(fm.descent - fm.ascent);

}

}

原文链接:http://www.apkbus.com/blog-192385-59653.html

0人推荐
随时随地看视频
慕课网APP