赞
踩
今天的文章关于android中最常用的的控件Textview,安卓中的TextView在文字布局的时候会在每行的末尾进行智能的换行分割,特别是有标点符号等出现的时候。这个规律是怎样的我至今还没有探究过。有兴趣的大家可以自己去看一下TextView的源码。项目中需要对文字进行较舒服的排布,去掉尾部的空缺,所以我对此给出来自己的解决方案,先看效果图吧。
绿色字体是用自定义的TextView加载的文字信息,没有限制最大行数。白色文字是用android系统的TextView。黄色文字是自定义的TextView,限制了最大行数,并且设置了显示自定义省略信息,就是在布局文件中调用android:ellipsize="end"。效果还是很明显的
我这里就简单粗暴的去重写Textview的onDraw方法了,而且没有super,完全是自己用Canvas去绘画每一个文字或者符号。所以一定程度上讲,这更像是一个View,丢失了很多TextView的特性,当然为了保留更多的Textview的特性,我也在里面重写了很多方法,新加入了一些方法。代码给出来,大家可以根据自己的需要自己去拓展。有很多原来TextView的函数都失去了作用,使用的时候请注意。
- import android.app.Activity;
- import android.content.Context;
- import android.graphics.Canvas;
- import android.graphics.Color;
- import android.graphics.Paint;
- import android.util.AttributeSet;
- import android.widget.TextView;
-
- /**
- * 自定义的文字整齐排版Textview控件,能让文字相对更加的整齐
- * <p>
- * 在xml布局文件中请加入命名空间"http://hdt.hdt/hdt"用于设置以下属性(单数字不填单位):
- * lineSpacingExtra,textSize,paddingLeft,paddingRight。 宽度请设置充满父布局, 目前只支持结尾省略...
- *
- * @author illidan.huang 杭州
- */
- public class MyTextView extends TextView {
-
- private final String namespace = "http://hdt.hdt/hdt";
- private String text;
- private float textSize;
- private Paint paint1 = new Paint();
- private float paddingLeft;
- private float paddingRight;
- private float textShowWidth;
- private int textColor;
- private float lineSpace;
- private int maxLines = Integer.MAX_VALUE;
- private boolean ellipsize = false;
- private float ellipsizeLength = 0;
- private String ellipsizeString = "(未完待续...)";
- // 初始化是否需要设置高度,不加判断则会无限的递归onDraw,自己看
- private boolean needHieght = true;
- private int lineCount = 0;
-
- public MyTextView(Context context, AttributeSet attrs) {
- super(context, attrs);
- // TODO Auto-generated constructor stub
- text = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "text");
- textSize = attrs.getAttributeIntValue(namespace, "textSize", 10);
- textColor = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "textColor", Color.WHITE);
- maxLines = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "maxLines", Integer.MAX_VALUE);
- String ell = attrs.getAttributeValue("http://schemas.android.com/apk/res/android", "ellipsize");
- ellipsize = "3".equals(ell);//android:ellipsize="end"对应的值是3,请看安卓源码
- paddingLeft = attrs.getAttributeIntValue(namespace, "paddingLeft", 0);
- paddingRight = attrs.getAttributeIntValue(namespace, "paddingRight", 0);
- lineSpace = attrs.getAttributeIntValue(namespace, "lineSpacingExtra", 3);
- float d = context.getResources().getDisplayMetrics().density;
- textSize = d * textSize + 0.5f;
- lineSpace = d * lineSpace + 0.5f;
- if(maxLines <= 0){
- maxLines = Integer.MAX_VALUE;
- }
- paint1.setTextSize(textSize);
- paint1.setColor(textColor);
- paint1.setAntiAlias(true);
- textShowWidth = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth() - paddingLeft - paddingRight;
- ellipsizeLength = paint1.measureText(ellipsizeString);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- int lineCount = 0;
- char[] textCharArray = text.toCharArray();
- float drawedWidth = 0;
- float charWidth;
- for (int i = 0; i < textCharArray.length; i++) {
- charWidth = paint1.measureText(textCharArray, i, 1);
- // 这里是用于,设置了最大行数和末尾省略的情况下进行的判断,16完全是我凭感觉给出的数字,没有为什么
- if (ellipsize && textShowWidth - drawedWidth - ellipsizeLength < 16) {
- if (lineCount == maxLines - 1) {
- canvas.drawText(ellipsizeString, paddingLeft + drawedWidth, (lineCount + 1) * textSize + lineSpace
- * lineCount, paint1);
- break;
- }
- }
- // 跳入下一行判断
- if (textShowWidth - drawedWidth < charWidth || textCharArray[i] == '\n') {
- lineCount++;
- if (lineCount > maxLines - 1) {
- lineCount--;
- break;
- }
- drawedWidth = 0;
- }
-
- canvas.drawText(textCharArray, i, 1, paddingLeft + drawedWidth, (lineCount + 1) * textSize + lineSpace * lineCount,
- paint1);
- drawedWidth += charWidth;
- }
- if (needHieght) {
- setHeight((lineCount + 1) * (int) (textSize + lineSpace));
- needHieght = false;
- }
- this.lineCount = lineCount;
- }
-
- @Override
- public void invalidate() {
- needHieght = true;
- super.invalidate();
- }
-
- @Override
- public void setText(CharSequence text, BufferType type) {
- // TODO Auto-generated method stub
- super.setText(text, type);
- this.text = String.valueOf(text);
- invalidate();
- }
-
- /**
- * 设置省略显示内容,默认"。。。"
- *
- * @param ellString
- */
- public final void setEllipsizeString(String ellString) {
- this.ellipsizeString = ellString;
- }
-
- /**
- * 设置结尾是否显示省略内容
- *
- * @param isEnd
- */
- public final void setEllipsizeEnd(boolean isEnd) {
- this.ellipsize = isEnd;
- }
-
- @Override
- public void setMaxLines(int maxlines) {
- this.maxLines = maxlines;
- if(this.maxLines <= 0){
- this.maxLines = Integer.MAX_VALUE;
- }
- super.setMaxLines(maxlines);
- }
-
- @Override
- public CharSequence getText() {
- return this.text;
- }
-
- /**
- * 设置行间距
- *
- * @param spa
- */
- public void setLineSpacingExtra(float spa) {
- this.lineSpace = spa;
- }
-
- @Override
- public int getLineCount() {
- return lineCount;
- }
-
- @Override
- public int getLineHeight() {
- return (int) (textSize+lineSpace);
- }
-
- @Override
- public float getTextSize() {
- return textSize;
- }
-
- @Override
- public void setSingleLine() {
- setSingleLine(true);
- }
-
- @Override
- public void setSingleLine(boolean singleLine) {
- if(singleLine){
- setMaxLines(1);
- }else{
- setMaxLines(Integer.MAX_VALUE);
- }
- }
-
- @Override
- public void setTextColor(int color) {
- this.textColor = color;
- paint1.setColor(color);
- super.setTextColor(color);
- }
-
- }
char[] textCharArray = text.toCharArray(); 按单词为单位进行分割,而不是一个字符char。
以下是图示的布局文件
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:hdt="http://hdt.hdt/hdt"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:background="@android:color/black"
- android:gravity="center_horizontal"
- android:orientation="vertical" >
-
-
- <ScrollView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content" >
-
-
- <LinearLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
-
-
- <com.wigit.MyTextView
- android:id="@+id/txt1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- hdt:paddingLeft="5"
- android:text="【一人之下,万人之上】《意林》卷一引《六韬》:“屈一人下,伸万人上,惟圣人能行之。”《汉书·萧何传》:“夫能诎於一人之下,而信於万乘之上者,汤武是也。”一人,谓天子;万人,谓百官。多指地位崇高权势显赫的大臣。【一人之交】好友;至交。谓亲密如一人。【一夫之用】谓仅能当一人之用,而无兼人之能。【一夫之勇】犹言匹夫之勇。"
- android:textColor="#FE8A08"
- hdt:lineSpacingExtra="3"
- hdt:textSize="16"
- ></com.wigit.MyTextView>"
-
-
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:paddingLeft="5dp"
- android:paddingRight="5dp"
- android:text="【一人之下,万人之上】《意林》卷一引《六韬》:“屈一人下,伸万人上,惟圣人能行之。”《汉书·萧何传》:“夫能诎於一人之下,而信於万乘之上者,汤武是也。”一人,谓天子;万人,谓百官。多指地位崇高权势显赫的大臣。【一人之交】好友;至交。谓亲密如一人。【一夫之用】谓仅能当一人之用,而无兼人之能。【一夫之勇】犹言匹夫之勇。"
- android:textColor="@android:color/white"
- android:textSize="16dp" />
-
- <com.wigit.MyTextView
- android:id="@+id/txt1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- hdt:paddingLeft="5"
- android:text="【一人之下,万人之上】《意林》卷一引《六韬》:“屈一人下,伸万人上,惟圣人能行之。”《汉书·萧何传》:“夫能诎於一人之下,而信於万乘之上者,汤武是也。”一人,谓天子;万人,谓百官。多指地位崇高权势显赫的大臣。【一人之交】好友;至交。谓亲密如一人。【一夫之用】谓仅能当一人之用,而无兼人之能。【一夫之勇】犹言匹夫之勇。"
- android:textColor="#FE8A08"
- hdt:lineSpacingExtra="3"
- hdt:textSize="16"
- android:maxLines="5"
- android:ellipsize="end"
- ></com.wigit.MyTextView>"
- </LinearLayout>
- </ScrollView>
-
-
- </LinearLayout>
若有不足请留言或者联系我,hdtpjhz@163.com
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。