/*
* Copyright (C) 2012 www.amsoft.cn
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.ab.view.sample;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint.FontMetrics;
import android.text.Layout;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.widget.TextView;
// TODO: Auto-generated Javadoc
/**
* © 2012 amsoft.cn
* 名称:AbTextView.java
* 描述:中英混合乱换行问题 .
*
* @author 还如一梦中
* @version v1.0
* @date:2013-05-17 下午6:46:29
*/
public class AbTextView extends TextView {
/** padding. */
private float leftPadding = 0;
/** The top padding. */
private float topPadding = 0;
/** The right padding. */
private float rightPadding = 0;
/** The bottom padding. */
private float bottomPadding = 0;
/** The line spacing. */
private float lineSpacing = 0;
/** 最大行数. */
private int maxLines = 1;
/** 文字大小. */
private float textSize = 14;
/** 文字颜色. */
private int textColor = Color.WHITE;
/** TextPaint. */
private TextPaint mTextPaint = null;
/**
* Instantiates a new ab text view.
*
* @param context the context
* @param attrs the attrs
*/
public AbTextView(Context context, AttributeSet attrs) {
super(context, attrs);
mTextPaint = this.getPaint();
mTextPaint.setColor(textColor);
mTextPaint.setTextSize(textSize);
}
/* (non-Javadoc)
* @see android.widget.TextView#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
// 清屏幕
canvas.drawColor(Color.TRANSPARENT);
drawText(canvas, this.getText().toString(), this.getWidth(), this.getPaint());
}
/**
* Sets the padding.
*
* @param left the left
* @param top the top
* @param right the right
* @param bottom the bottom
*/
@Override
public void setPadding(int left,int top,int right,int bottom){
leftPadding = left;
topPadding = top;
rightPadding = right;
bottomPadding = bottom;
this.invalidate();
}
/**
* Sub string length.
*
* @param str the str
* @param maxPix the max pix
* @param paint the paint
* @return the int
*/
public int subStringLength(String str, int maxPix, TextPaint paint) {
if (TextUtils.isEmpty(str)) {
return 0;
}
int currentIndex = 0;
for (int i = 0; i < str.length(); i++) {
// 获取一个字符
String temp = str.substring(0, i + 1);
float valueLength = paint.measureText(temp)+leftPadding+rightPadding;
if (valueLength > maxPix) {
currentIndex = i - 1;
break;
} else if (valueLength == maxPix) {
currentIndex = i;
break;
}
}
// 短于最大像素返回最后一个字符位置
if (currentIndex == 0) {
currentIndex = str.length() - 1;
}
return currentIndex;
}
/**
* Gets the string width.
*
* @param str the str
* @param paint the paint
* @return the string width
*/
public float getStringWidth(String str, TextPaint paint) {
float strWidth = paint.measureText(str);
return strWidth;
}
/**
* Gets the desired width.
*
* @param str the str
* @param paint the paint
* @return the desired width
*/
public float getDesiredWidth(String str, TextPaint paint) {
float strWidth = Layout.getDesiredWidth(str, paint);
return strWidth;
}
/**
* Gets the draw row str.
*
* @param text the text
* @param maxWPix the max w pix
* @param paint the paint
* @return the draw row str
*/
public List<String> getDrawRowStr(String text, int maxWPix,
TextPaint paint) {
String[] texts = null;
if (text.indexOf("\n") != -1) {
texts = text.split("\n");
} else {
texts = new String[1];
texts[0] = text;
}
// 共多少行
List<String> mStrList = new ArrayList<String>();
for (int i = 0; i < texts.length; i++) {
String textLine = texts[i];
// 计算这个文本显示为几行
while (true) {
// 可容纳的最后一个字的位置
int endIndex = subStringLength(textLine, maxWPix, paint);
if (endIndex <= 0) {
mStrList.add(textLine);
} else {
if (endIndex == textLine.length() - 1) {
mStrList.add(textLine);
} else {
mStrList.add(textLine.substring(0, endIndex + 1));
}
}
// 获取剩下的
if (textLine.length() > endIndex + 1) {
// 还有剩下的
textLine = textLine.substring(endIndex + 1);
} else {
break;
}
}
}
return mStrList;
}
/**
* Gets the draw row count.
*
* @param text the text
* @param maxWPix the max w pix
* @param paint the paint
* @return the draw row count
*/
public int getDrawRowCount(String text, int maxWPix, TextPaint paint) {
String[] texts = null;
if (text.indexOf("\n") != -1) {
texts = text.split("\n");
} else {
texts = new String[1];
texts[0] = text;
}
// 共多少行
List<String> mStrList = new ArrayList<String>();
for (int i = 0; i < texts.length; i++) {
String textLine = texts[i];
// 计算这个文本显示为几行
while (true) {
// 可容纳的最后一个字的位置
int endIndex = subStringLength(textLine, maxWPix, paint);
if (endIndex <= 0) {
mStrList.add(textLine);
} else {
if (endIndex == textLine.length() - 1) {
mStrList.add(textLine);
} else {
mStrList.add(textLine.substring(0, endIndex + 1));
}
}
// 获取剩下的
if (textLine.length() > endIndex + 1) {
// 还有剩下的
textLine = textLine.substring(endIndex + 1);
} else {
break;
}
}
}
return mStrList.size();
}
/**
* Draw text.
*
* @param canvas the canvas
* @param text the text
* @param maxWPix the max w pix
* @param paint the paint
* @return the int
*/
public int drawText(Canvas canvas, String text, int maxWPix,
TextPaint paint) {
if (TextUtils.isEmpty(text)) {
return 1;
}
// 需要根据文字长度控制换行
// 测量文字的长度
List<String> mStrList = getDrawRowStr(text, maxWPix, paint);
FontMetrics fm = paint.getFontMetrics();
int hSize = (int)Math.ceil(fm.descent - fm.ascent);
for (int i = 0; i < mStrList.size(); i++) {
// 计算坐标
float x = leftPadding;
float y = topPadding+hSize/2+i*(hSize+lineSpacing)+bottomPadding;
String textLine = mStrList.get(i);
if(i < maxLines){
canvas.drawText(textLine, x, y, paint);
}
}
return mStrList.size();
}
/**
* Gets the max lines.
*
* @return the max lines
*/
@SuppressLint("Override")
public int getMaxLines(){
return maxLines;
}
/* (non-Javadoc)
* @see android.widget.TextView#setMaxLines(int)
*/
@Override
public void setMaxLines(int maxLines){
this.maxLines = maxLines;
this.invalidate();
}
/**
* Gets the line spacing.
*
* @return the line spacing
*/
public float getLineSpacing(){
return lineSpacing;
}
/**
* Sets the line spacing.
*
* @param lineSpacing the new line spacing
*/
public void setLineSpacing(float lineSpacing){
this.lineSpacing = lineSpacing;
}
/* (non-Javadoc)
* @see android.widget.TextView#setTextSize(float)
*/
@Override
public void setTextSize(float size) {
this.textSize = size;
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
setRawTextSize(TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, size, r.getDisplayMetrics()));
}
/**
* Sets the raw text size.
*
* @param size the new raw text size
*/
private void setRawTextSize(float size) {
if (size != mTextPaint.getTextSize()) {
mTextPaint.setTextSize(size);
this.invalidate();
}
}
/* (non-Javadoc)
* @see android.widget.TextView#getTextSize()
*/
public float getTextSize(){
return textSize;
}
/**
* Gets the text color.
*
* @return the text color
*/
public int getTextColor(){
return textColor;
}
/* (non-Javadoc)
* @see android.widget.TextView#setTextColor(int)
*/
@Override
public void setTextColor(int textColor){
this.textColor = textColor;
mTextPaint.setColor(textColor);
this.invalidate();
}
}