[置顶] android 自定义TextView
系统自带的控件TextView有时候没满一行就换行了,为了解决这个问题,自定义了一个TextView,只有一行显示不完全的情况下才会去换行显示,代码如下:
package com.open.textview; import java.util.ArrayList; import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View; /**
* 不换行的TextView
* @author Administrator
*
*/
public class CusTextView extends View { protected float textSize=35;
protected float paddingLeft=0;
protected float paddingRight=0;
protected float paddingTop=0;
protected float paddingBottom=0; protected float lineSpace=5;
protected int lineWidth=320;
protected float lineHeight=20;
protected int lineCount;
protected int maxLines=-1;//最大的行数 protected String mText;
protected ArrayList<LineParams> lineList=new ArrayList<LineParams>(0);//行的字符串索引 protected Paint mPaint = new Paint();
{
mPaint.setTextSize(textSize);
mPaint.setAntiAlias(true);
} public CusTextView(Context context) {
super(context);
} public CusTextView(Context context, AttributeSet attrs) {
super(context, attrs);
} public CusTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public void setText(String text) {
this.mText = text;
lineList.clear();
requestLayout();
invalidate();
} public void setText(String text,int maxLines)
{
this.maxLines=maxLines;
this.setText(text);
} @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { if(TextUtils.isEmpty(mText))
{
setMeasuredDimension(0, 0);
return;
} lineWidth=(int)(MeasureSpec.getSize(widthMeasureSpec)-paddingLeft-paddingRight);//每行的宽度
Rect bounds = new Rect();
mPaint.getTextBounds(mText, 0, mText.length(), bounds);
lineHeight=bounds.bottom-bounds.top; maxLines=-1;
lineList.clear();
calculate();
lineCount=lineList.size();//总行数
maxLines=(maxLines>0)?Math.min(lineCount, maxLines):lineCount; int measuredHeight=0;//总的高度
if(maxLines>0)
{
measuredHeight+=(paddingTop+paddingBottom);//顶部与底部
measuredHeight+=(maxLines-1)*lineSpace;//空隙的间隔
measuredHeight+=(maxLines*(lineHeight));//行高之和
} int result=measuredHeight;
int specMode = MeasureSpec.getMode(heightMeasureSpec);
int specSize = MeasureSpec.getSize(heightMeasureSpec);
switch (specMode) {
case MeasureSpec.UNSPECIFIED:
result = measuredHeight;
break;
case MeasureSpec.AT_MOST:
result = Math.min(measuredHeight, specSize);
break;
case MeasureSpec.EXACTLY:
result = specSize;
break;
}
setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), result);
} @Override
protected void onDraw(Canvas canvas) { if(TextUtils.isEmpty(mText))
{
return;
} for(int i=0;i<lineList.size();i++)
{
if(i==0)
{
canvas.drawText(mText, lineList.get(i).startIndex, lineList.get(i).endIndex, paddingLeft, paddingTop+lineHeight, mPaint);
}
else
{
canvas.drawText(mText, lineList.get(i).startIndex, lineList.get(i).endIndex, paddingLeft, paddingTop+lineHeight+(lineHeight+lineSpace)*i, mPaint);
}
} } private void calculate()
{
int startIndex=0;
while(true)
{
int[] itemLine=getIndexArray(startIndex);
lineList.add(new LineParams(itemLine[0], itemLine[1]));
if(itemLine[1]>=mText.length())
{
break;
} startIndex=itemLine[1];
}
} private int[] getIndexArray(int startIndex)
{
int[] ret=new int[2]; int canholdcharSize=0;
int singleCharWidth=(int) mPaint.measureText(mText, startIndex, startIndex+1);//单个字符宽度
singleCharWidth=Math.max(singleCharWidth, 1);
canholdcharSize=lineWidth/singleCharWidth;//每行可以容纳的字数,非精确值 if(isOutOfIndex(startIndex,canholdcharSize))//检查是否越界了
{
canholdcharSize=mText.length()-startIndex;
} if(isFitness(startIndex,canholdcharSize,lineWidth))//如果linecharSize个字符还小于单行的长度,需要再次自加长度来判断
{
while(true)
{
canholdcharSize++;
if(isOutOfIndex(startIndex,canholdcharSize))
{
canholdcharSize--;
break;
} if(isFitness(startIndex,canholdcharSize,lineWidth))
{
continue;
}
else
{
canholdcharSize--;
break;
}
}
}
else //需要再次自减长度来判断
{
while(true)
{
canholdcharSize--;
if(isFitness(startIndex,canholdcharSize,lineWidth))
{
break;
}
else
{
continue;
}
}
} ret[0]=startIndex;
ret[1]=(startIndex+canholdcharSize);
return ret;
} private boolean isOutOfIndex(int startIndex,int linecharSize)
{
return startIndex+linecharSize>mText.length();
} private boolean isFitness(int startIndex,int canholdcharSize,int lineWidth)
{
return mPaint.measureText(mText, startIndex, startIndex+canholdcharSize)<=lineWidth;
} public class LineParams
{
public int startIndex;
public int endIndex; public LineParams(int startIndex, int endIndex)
{
this.startIndex = startIndex;
this.endIndex = endIndex;
} public boolean isInnerRange(int testNum)
{
return (testNum>=startIndex&&testNum<=endIndex);
} @Override
public String toString()
{
return "LineParams [startIndex=" + startIndex + ", endIndex="+ endIndex + "]";
}
}
}
Demo地址:http://download.csdn.net/detail/zz7zz7zz/6015937
邮箱:zz7zz7zz@163.com
微博:http://weibo.com/u/3209971935
[置顶] android 自定义TextView的更多相关文章
- [置顶] android 自定义ListView实现动画特效
通过自定义ListView实现动画特效,被点击元素A向前移,A之前元素往后移动. 重点在于动画的实现: 具体代码如下: package com.open.widget; import java.uti ...
- [置顶] Android EditText/TextView使用SpannableString显示复合文本
在Android中EditText用于编辑文本,TextView用于显示文本,但是有时候我们需要对其中的文本进行样式等方面的设置.Android为我们提供了SpannableString类来对指定文本 ...
- [置顶] android 自定义圆角ImageView以及锯齿的处理
看到很多人开发过程中要使用圆角图片时,解决方法有: 1.重新绘制一张图片 2.通过布局来配置 3.通过重写View来实现 其中1,2在这里就不讲了,重点讲讲方法三的实现. 实现一:通过截取画布一个圆形 ...
- [置顶]
Android RadioButton与TextView浪漫约会?
情景一 今天主要实现一个国家与地区切换,就是当我们选中RadioButton时然后将值设置到TextView中,听着这需求应该不难对吧?那么我们就开始约会吧? 看下原型图 准备条件: 首先需要一个ra ...
- [置顶] Android开发笔记(成长轨迹)
分类: 开发学习笔记2013-06-21 09:44 26043人阅读 评论(5) 收藏 Android开发笔记 1.控制台输出:called unimplemented OpenGL ES API ...
- [置顶] Android布局管理器 - 详细解析布局实现
布局管理器都是以ViewGroup为基类派生出来的; 使用布局管理器可以适配不同手机屏幕的分辨率,尺寸大小; 布局管理器之间的继承关系 : 在上面的UML图中可以看出, 绝对布局 帧布局 网格布局 相 ...
- Android 自定义TextView 实现文本间距
Android系统中TextView默认显示中文时会比较紧凑,不是很美观.为了让每行保持一定的行间距,可以设置属性android:lineSpacingExtra或android:lineSpacin ...
- [置顶] android开发之来电自动拒接并自动回复短信_上课模式app
上课的时候老师说总是错过电话,对方打来没人接还一遍遍的打,觉得可以有个app在上课期间自动拒接电话,并自动回复短信过去. 当然了,需要权限的. 尝试做了个雏形出来. 界面如下: 主要代码如下: pac ...
- [置顶] Android事件—单选按键和下拉按键
在平常的开发中单选按键和下拉按键是非常常用的2个点击事件.首先介绍下单选按键 1:单选按键,单选的主键是radiogroup 这个主键也是很重要的 首先介绍下主键的布局 <?xml versio ...
随机推荐
- Linux下安装JRE
(1)下载jre-7u5-linux-i586.tar.gz,上传至/root目录 (2)执行tar -zxf jre-7u5-linux-i586.tar.gz (3)mv jre1.7.0_05 ...
- jbpmAPI-1
1.1. What is jBPM? jBPM是一个灵活的业务流程管理(BPM)套件.它是轻量级的,完全开源Apache许可下(分布式),用Java编写的.它允许您模型.执行和监控业务流程的整个生命周 ...
- 软件源(Software Sources)
写在前面:浏览了很多国内外的网站,看了很多关于软件源(Software Sources)设置的文章,发现有很多文章中对软件源的设置存在误解,为了让新人能顺利进入Ubuntu的大家庭,特地作此文,详细地 ...
- 让Qt支持Win7的Aero和毛玻璃效果
Qt5增加了许多特性,其中 Qt Windows Extras 模块就增加了对Win7 Aero 效果的支持. 官网的介绍如下: Qt Windows Extras provide classes a ...
- QT直接支持GB18030,附它对此编码的一堆相关文档描述
http://doc.qt.io/qt-5/qtextcodec.html http://doc.qt.io/qt-5/codec-gbk.html
- PHP 自学之路-----XML编程(Xpath技术,simpleXml技术)基础入门
XPAth技术 XPath的设计的核心思想,可以通过xpath迅速简介的定位到你希望查找的节点.主要目的是描述节点相对其他节点的位置,可以取得所有符合条件的节点,成为[位置路径]. Xapth主要用来 ...
- Hive实现oracle的Minus函数
在Oracle中minus运算的主要功能是: 在进行两个表格或者两个查询结果的时候,返回在第一个表格/查询结果中与第二个表格/查询结果不同样的记录. 结果不同样的记录包括两种情况:A,B 表中某一行的 ...
- 已经上架的app(可供销售)在AppStore上搜不到的解决办法
这两天很是头大, 因为3天前手动发布的app到现在都还没在AppStore上看到,打了无数电话给苹果和发邮件给review团队. 下面说说怎么解决我们在iTunes后台看到是绿灯(可供销售)但是就是在 ...
- iOS 判断有无网络连接
众所周知,我们在开发APP时,涉及网络连接的时候,都会想着提前判断一下当前的网络连接状态,如果没有网络,就不再请求url,省去不必要的步骤,所以,这个如何判断?其实很简单. 前提:工程添加:Syste ...
- ETHERNET帧结构
以太网帧http://blog.csdn.net/guoshaobei/article/details/4768514 Ethernet的帧格式 (转) http://jiangqiaosun.bl ...