Android TextView默認是標點符號不能再行尾和行首,英文單詞不能拆分;
1、網上有說修改源碼(表示我是菜鳥)、也有說轉半角或全角(這種真的不太行啊,半角的話還是有點問題;全角的話英文就難看了,顯示出來只能呵呵~~。)
2、自定義(我是還是很贊同的),下面是我看了網上別人的自定義代碼寫出來的(不喜勿噴),先上代碼:
/**
* Created by wmi01 on 2015/11/23.
* 文字排版自動換行
*/
public class ComposeTextView extends View {
// 總高度、寬度
private int sumHeight = 0;
private int maxWidth = 0;
// 一些屬性
private int textColor = getResources().getColor(android.R.color.black);
private int textSize = 14;
private int lineSpace = 5; //行間距
private int typeFace = 0;
private String text = "";
private int maxLine = Integer.MAX_VALUE; //最大行數
// 上下左右的距離
private int left_Margin = 10;
private int right_Margin = 10;
private int top_Margin = 10;
private int bottom_Margin = 10;
private Paint mPaint;
public ComposeTextView(Context context) {
super(context);
}
public ComposeTextView(Context context, AttributeSet attrs) {
super(context, attrs, 0);
DisplayMetrics dm = getResources().getDisplayMetrics();
//爲屬性定義單位
textSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, textSize, dm);
lineSpace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, lineSpace, dm);
left_Margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, left_Margin, dm);
right_Margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, right_Margin, dm);
top_Margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, top_Margin, dm);
bottom_Margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, bottom_Margin, dm);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ComposeTextView);
textSize = a.getDimensionPixelSize(R.styleable.ComposeTextView_textSize, textSize);
textColor = a.getColor(R.styleable.ComposeTextView_textColor, textColor);
lineSpace = a.getDimensionPixelSize(R.styleable.ComposeTextView_lineSpace, lineSpace);
maxLine = a.getInt(R.styleable.ComposeTextView_maxLine, maxLine);
typeFace = a.getInt(R.styleable.ComposeTextView_typeFace, typeFace);
left_Margin = a.getDimensionPixelSize(R.styleable.ComposeTextView_left_Margin, left_Margin);
right_Margin = a.getDimensionPixelSize(R.styleable.ComposeTextView_right_Margin, right_Margin);
top_Margin = a.getDimensionPixelSize(R.styleable.ComposeTextView_top_Margin, top_Margin);
bottom_Margin = a.getDimensionPixelSize(R.styleable.ComposeTextView_bottom_Margin, bottom_Margin);
a.recycle();
int width = dm.widthPixels;
maxWidth = width - left_Margin - right_Margin;
mPaint = new Paint();
mPaint.setAntiAlias(true);// 抗鋸齒
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
switch (typeFace) {
case 0:
mPaint.setTypeface(Typeface.DEFAULT);
break;
case 1:
mPaint.setTypeface(Typeface.SANS_SERIF);
break;
case 2:
mPaint.setTypeface(Typeface.SERIF);
break;
case 3:
mPaint.setTypeface(Typeface.MONOSPACE);
break;
default:
mPaint.setTypeface(Typeface.DEFAULT);
break;
}
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int lineWidth = 0; //字符串所佔行寬
int lineHeight = 0; //行高
int lineNum = 0; //總行數
int start = 0; //定位:用於截取字符串
char ch;
int x = 0;
int y = 30; //爲了讓文字可以顯示出來,不至於被遮蓋,特別是第一行,這個值要根據字體大小設置,可以設置一個值用來動態控制。
Vector<String> mString = new Vector<String>();
Paint.FontMetrics fontMetrics = mPaint.getFontMetrics();
lineHeight = (int) (Math.ceil(fontMetrics.descent - fontMetrics.top) + lineSpace);
// y += Math.ceil(fontMetrics.descent);
for (int i = 0; i < text.length(); i++) {
ch = text.charAt(i);
String str = String.valueOf(ch);
float widths[] = new float[1];
mPaint.getTextWidths(str, widths);
if (ch == '\n') {
lineNum++;
mString.addElement(text.substring(start, i));
start = i + 1;
lineWidth = 0;
} else {
lineWidth += Math.ceil(widths[0]);
if (lineWidth > maxWidth) {
lineNum++;
mString.addElement(text.substring(start, i));
start = i;
i--;
lineWidth = 0;
} else {
if (i == text.length() - 1) {
lineNum++;
mString.addElement(text.substring(start, text.length()));
}
}
}
//判斷行數是否大於最大行數
if (lineNum > maxLine) {
lineNum = lineNum < maxLine ? lineNum : maxLine;
float dotWidths[] = new float[3];
String dot = "...";
mPaint.getTextWidths(dot, dotWidths);
int dotWidth = 0;
for (int j = 0; j < 3; j++) {
dotWidth += Math.ceil(dotWidths[j]);
}
String string = (String) mString.elementAt(lineNum - 1);
lineWidth = 0;
for (int j = string.length() - 1; j >= 0; j--) {
float stringWidths[] = new float[j + 1];
String stringSub = string.substring(0, j + 1);
mPaint.getTextWidths(stringSub, stringWidths);
for (int k = 0; k < stringSub.length(); k++) {
lineWidth += Math.ceil(stringWidths[k]);
}
if (lineWidth + dotWidth <= maxWidth) {
while (mString.size() > lineNum - 1) {
mString.remove(mString.size() - 1);
}
mString.addElement(stringSub + dot);
break;
}
lineWidth = 0;
}
break;
}
}
sumHeight = lineHeight * lineNum - lineSpace;
for (int i = 0; i < lineNum; i++) {
//其實設置y的只就是爲了迎合這個函數,要是不清楚可以自己百度一下
canvas.drawText((String) mString.elementAt(i), x, y + lineHeight
* i, mPaint);
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int measuredWidth = measuredWidth(widthMeasureSpec);
int measuredHeight = measuredHeight(heightMeasureSpec);
this.setMeasuredDimension(measuredWidth, measuredHeight);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(
measuredWidth, measuredHeight);
params.topMargin = top_Margin;
params.bottomMargin = bottom_Margin;
params.leftMargin = left_Margin;
params.rightMargin = right_Margin;
this.setLayoutParams(params);
}
private int measuredHeight(int heightMeasureSpec) {
int specMode = MeasureSpec.getMode(heightMeasureSpec);
int specSize = MeasureSpec.getSize(heightMeasureSpec);
initHeight();
// Default size if no limits specified.
int result = sumHeight;
if (specMode == MeasureSpec.AT_MOST) {
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
result = sumHeight;
}
return result;
}
/**
* 初始化高度
*/
private void initHeight() {
int lineHeight = 0;
int lineNum = 0;
int lineWidth = 0;
FontMetrics fontMetrics = mPaint.getFontMetrics();
lineHeight = (int) (Math.ceil(fontMetrics.descent - fontMetrics.top) + lineSpace);
for (int i = 0; i < text.length(); i++) {
char ch = text.charAt(i);
String str = String.valueOf(ch);
float widths[] = new float[1];
mPaint.getTextWidths(str, widths);
if (ch == '\n') {
lineNum++;
lineWidth = 0;
} else {
lineWidth += Math.ceil(widths[0]);
if (lineWidth > maxWidth) {
lineNum++;
i--;
lineWidth = 0;
} else {
if (i == text.length() - 1) {
lineNum++;
}
}
}
if (lineNum > maxLine) {
lineNum = lineNum < maxLine ? lineNum : maxLine;
break;
}
}
sumHeight = lineNum * lineHeight - lineSpace;
}
private int measuredWidth(int heightMeasureSpec) {
int specMode = MeasureSpec.getMode(heightMeasureSpec);
int specSize = MeasureSpec.getSize(heightMeasureSpec);
// Default size if no limits specified.
int result = maxWidth;
if (specMode == MeasureSpec.AT_MOST) {
result = specSize;
} else if (specMode == MeasureSpec.EXACTLY) {
result = maxWidth;
}
return result;
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
this.textColor = textColor;
}
public int getTextSize() {
return textSize;
}
public void setTextSize(int textSize) {
this.textSize = textSize;
}
public int getLineSpace() {
return lineSpace;
}
public void setLineSpace(int lineSpace) {
this.lineSpace = lineSpace;
}
public int getTypeFace() {
return typeFace;
}
public void setTypeFace(int typeFace) {
this.typeFace = typeFace;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
public int getLeft_Margin() {
return left_Margin;
}
public void setLeft_Margin(int left_Margin) {
this.left_Margin = left_Margin;
}
public int getRight_Margin() {
return right_Margin;
}
public void setRight_Margin(int right_Margin) {
this.right_Margin = right_Margin;
}
public int getTop_Margin() {
return top_Margin;
}
public void setTop_Margin(int top_Margin) {
this.top_Margin = top_Margin;
}
public int getBottom_Margin() {
return bottom_Margin;
}
public void setBottom_Margin(int bottom_Margin) {
this.bottom_Margin = bottom_Margin;
}
public int getMaxLine() {
return maxLine;
}
public void setMaxLine(int maxLine) {
this.maxLine = maxLine;
}
}
在attrs.xml中
<!-- 自定義TextView換行-->
<declare-styleable name="ComposeTextView">
<attr name="textColor" format="color|reference" />
<attr name="textSize" format="dimension" />
<attr name="lineSpace" format="dimension" />
<attr name="maxLine" format="integer" />
<attr name="typeFace">
<enum name="normal" value="0" />
<enum name="sans" value="1" />
<enum name="serif" value="2" />
<enum name="monospace" value="3" />
</attr>
<attr name="left_Margin" format="dimension" />
<attr name="right_Margin" format="dimension" />
<attr name="top_Margin" format="dimension" />
<attr name="bottom_Margin" format="dimension" />
</declare-styleable>
然後在代碼中的應用:
<com.example.ui.views.ComposeTextView
android:id="@+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="@style/base_text_desc_style"/>
<style name="base_text_desc_style">
<item name="com.example.ui:textSize">16sp</item>
<item name="com.example.ui:typeFace">sans</item>
<item name="com.example.ui:maxLine">5</item>
<item name="com.example.ui:lineSpace">5dp</item>
<item name="com.example.ui:textColor">#333333</item>
</style>
在Activity中的使用:
public class MainActivity extends FragmentActivity {
String text = "Android是一種基於Linux的自由及開放源代碼的操作系統,主要使用於移動設備,如智能手機和平板電腦,由Google公司和開放手機聯盟領導及開發。尚未有統一中文名稱,中國大陸地區較多人使用“安卓”或“安致”。Android操作系統最初由Andy Rubin開發,主要支持手機。2005年8月由Google收購注資。2007年11月,Google與84家硬件製造商、軟件開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨後Google以Apache開源許可證的授權方式,發佈了Android的源代碼。第一部Android智能手機發佈於2008年10月。Android逐漸擴展到平板電腦及其他領域上,如電視、數碼相機、遊戲機等。2011年第一季度,Android在全球的市場份額首次超過塞班系統,躍居全球第一。 2013年的第四季度,Android平臺手機的全球市場份額已經達到78.1%。[1] 2013年09月24日谷歌開發的操作系統Android在迎來了5歲生日,全世界採用這款系統的設備數量已經達到10億臺。";
protected ComposeTextView composeTextView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
composeTextView = (ComposeTextView) findViewById(R.id.tv);
composeTextView.setText(text);
}
}