Android自定义TextView排版优化
来源:互联网 发布:单片机 脉冲信号 编辑:程序博客网 时间:2024/05/16 12:08
今天的文章关于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); }}
英文的实现效果我这里暂时未考虑到,需要的话,我给个思路。就是在onDraw函数中,对文字进行分词的时候
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
0 0
- Android自定义TextView排版优化
- android 自定义textView,实现排版对齐和换行
- android自定义view解决textview显示排版的问题
- android 自定义textView,实现排版对齐和换行
- android 自定义textView,实现排版对齐和换行
- Android重写textview排版
- Android TextView排版
- 解决TextView排版不齐问题----自定义TextVIew
- android textview 排版混乱问题
- android textview文字自动排版
- JustifyTextView 自定义TextView解决中文排版
- Android 自定义TextView 实现文字对齐排版且支持点击划词
- 【TextView】自定义TextView中文换行排版问题修复
- 诡异的Android TextView排版布局问题
- Android TextView 解决文字换行排版
- android textView 排版显示参差不齐的解决方法
- 解决Android的TextView排版问题
- android textview 自动换行 整齐排版
- 在eclipse中将android项目生成apk并且给apk签名
- 杭电ACM 2021
- DataSet导出到Excel,并生成文件(C#实现,可合并行和列)
- acm_icpc网络赛第一站:牡丹江赛区
- jquery---5
- Android自定义TextView排版优化
- 解题报告——直线整点数量问题总结
- C#初入串口通信(串行通信)总结
- 关于linux报bash ‘/bin/sh: Syntax error: “(” unexpected
- OpenFlow1.0协议解析
- Python学习杂记十三
- Java的多线程机制
- BJFUOJ 1042解题报告(DFS回溯策略总结)
- Linux文件