android settext文字换行n,自定义TextView,解决文字换行,\n换行符换行,导致高度计算不对问题(计算ListView高度)...

看了这篇文章之后 确实 楼主写的 要比上边的一段好一些 后来发现还是有计算换行的问题。

发现这篇文章 http://www.jianshu.com/p/d916a667c611

有说关于TextView 有标点符号换行问题

不过textview的折行包含以下规律:

1、半角字符与全角字符混乱所致:这种情况一般就是汉字与数字、英文字母混用。

2、TextView在显示中文的时候标点符号不能显示在一行的行首和行尾,如果一个标点符号刚好在一行的行尾,该标点符号就会连同前一个字符跳到下一行显示。

3、一个英文单词不能被显示在两行中( TextView在显示英文时,标点符号是可以放在行尾的,但英文单词也不能分开 )。

public static String ToDBC(String input) {

char c[] = input.toCharArray();

for (int i = 0; i < c.length; i++) {

if (c[i] == '\u3000') { //空格

c[i] = ' ';

} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { //半角与全角相差 65248

c[i] = (char) (c[i] - 65248);

}

}

return new String(c);

}

最后结合需求 这样的一点小的改动

public class MTextView extends TextView {

private Context context;

public MTextView(Context context) {

super(context);

// TODO Auto-generated constructor stub

this.context = context;

}

public MTextView(Context context, AttributeSet attrs) {

super(context, attrs);

// TODO Auto-generated constructor stub

this.context = context;

}

public MTextView(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

// TODO Auto-generated constructor stub

this.context = context;

}

@Override

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

int mode = MeasureSpec.getMode(heightMeasureSpec);

Layout layout = getLayout();

if (layout != null) {

int height = (int) Math.ceil(getMaxLineHeight(ToDBC(this.getText().toString()), mode))

+ getCompoundPaddingTop() + getCompoundPaddingBottom();

int width = getMeasuredWidth();

setMeasuredDimension(width, height);

}

}

private float getMaxLineHeight(String str, int mode) {

float height = 0.0f;

float width = getMeasuredWidth();

float widthPixels = context.getResources().getDisplayMetrics().widthPixels;

//这里具体this.getPaint()要注意使用,要看你的TextView在什么位置,

// 这个是拿TextView父控件的Padding的,为了更准确的算出换行

float pLeft = ((LinearLayout) getParent()).getPaddingLeft();

float pRight = ((LinearLayout) getParent()).getPaddingRight();

//检测字符串中是否包含换行符,获得换行的次数,在之后计算高度时加上

int br = 0;

if (str.contains("\n"))

br = str.split("\n").length - 1;

/**

* wrap_content/未指定宽度(MeasureSpec.UNSPECIFIED),则用屏幕宽度计算

* 否则就使用View自身宽度计算,并且无需计算Parent的Padding

*/

int line;

if (mode == MeasureSpec.UNSPECIFIED)

line = (int)

Math.ceil((this.getPaint().measureText(str) /

(widthPixels - getPaddingLeft() - pLeft - pRight - getPaddingRight())));

else {

line = (int)

Math.ceil((this.getPaint().measureText(str) /

(width - getPaddingLeft() - getPaddingRight())));

}

height = (this.getPaint().getFontMetrics().descent -

this.getPaint().getFontMetrics().ascent) * (line + br);

return height;

}

public static String ToDBC(String input) {

char c[] = input.toCharArray();

for (int i = 0; i < c.length; i++) {

if (c[i] == '\u3000') { //空格

c[i] = ' ';

} else if (c[i] > '\uFF00' && c[i] < '\uFF5F') { //半角与全角相差 65248

c[i] = (char) (c[i] - 65248);

}

}

return new String(c);

}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值