android textview 排版混乱问题

    最近在做文字排版,对于几段文字如果直接用setText,会出现排版混乱现象(末尾如果是标点符号,会和前一个字自动换行)

    在网上查了下资料,是android 本身就有这个问题。有说把半角改成全角,但是还是会出现这样的问题。于是只好自己重写了个TextView来排版。网上也有一些人自己实现了,但是好象都挺麻烦的。我针对自己的需要写了个简单的。(不足的是这个TextView还没做自适应,暂时是固定宽度的,自适应需要的可以自己优化);

    原理就是计算一行文字的宽度,如果超出了一行宽度,就从下一行开始排。这里有个地方要注意,因为可能文字里包含了多段文本,因此先要分离出每段的"\n"再对一段没有换行符的文字进行每行计算。一开始的时候用最苯的方法,一个字一个字的去计算宽度,虽然实现了效果但是如果文本多了初始化超慢。于是又重新想了一个算法,速度立刻快了很多。

代码如下:

public class JDTextView extends TextView 
{
	private StringBuffer mText;
	/**间隔*/
	private int mMarginTop = 0;
	private StringBuffer newText = new StringBuffer();
	private Paint mPaint;
	/**VIEW的高度*/
	private int mHeight = 0;
	/**行高*/
	private static final int LINE_HEIGHT = 40;
	/**第一行的位置,因为TEXTVIEW 是从左下角开始算位置的*/
	private static final int FIRST_PADDING = 20;
	public ClassicalTextView(Context context)
	{
		super(context);
	}

	@Override
	protected void onDraw(Canvas canvas)
	{
		super.onDraw(canvas);
		int index = newText.indexOf("\n");
		String lineStr;
		mMarginTop = FIRST_PADDING;
		String tempStr = newText.toString();
		while(index != -1)
		{
			lineStr = tempStr.substring(0, index);
			canvas.drawText(lineStr, 0, mMarginTop, mPaint);
			tempStr = tempStr.substring(index + 1);
			index = tempStr.indexOf("\n");
			mMarginTop += LINE_HEIGHT;
		}
	}
	
	/**
	* @Description:计算出一行显示的文字
	* @param     设定文件
	*/
	private String caculateOneLine(String str)
	{
		//对一段没有\n的文字进行换行
		String returnStr = "";
		int strWidth = (int) mPaint.measureText(str);
		int len = str.length();
		int lineNum = strWidth/620;	//大概知道分多少行
		int oneLine;
		int tempWidth = 0;
		String lineStr;
		int returnInt = 0;
		if(lineNum == 0)
		{
			returnStr = str;
			mHeight += LINE_HEIGHT;
			return returnStr;
		}
		else
		{
			oneLine = len/(lineNum + 1);	//一行大概有多少个字
			lineStr = str.substring(0, oneLine);
			tempWidth = (int) mPaint.measureText(lineStr);
			if(tempWidth < 620)	//如果小了 找到大的那个
			{
				while(tempWidth < 620)
				{
					oneLine++;
					lineStr = str.substring(0, oneLine);
					tempWidth = (int) mPaint.measureText(lineStr);
				}
				returnInt = oneLine - 1;
				returnStr = lineStr.substring(0, lineStr.length() - 2);
			}
			else
			{
				while(tempWidth > 620)
				{
					oneLine--;
					lineStr = str.substring(0, oneLine);
					tempWidth = (int) mPaint.measureText(lineStr);
				}
				returnStr = lineStr.substring(0, lineStr.length() - 1);
				returnInt = oneLine;
			}
			mHeight += LINE_HEIGHT;
			returnStr += "\n" + caculateOneLine(str.substring(returnInt-1));
		}
		return returnStr;
	}
	
	public void caculateChangeLine()
	{
		String tempStr[] = mText.toString().split("\n");
		int len = tempStr.length;
		for(int i=0;i<len;i++)
		{
			newText.append(caculateOneLine(tempStr[i]));
			newText.append("\n");
		}
		this.setHeight(mHeight);
	}
		
	public void setText(String text)
	{
		mText = new StringBuffer(text);
		mPaint = this.getPaint();
		caculateChangeLine();
	}
	
} 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值