自定义TextView,解决文字换行,\n换行符换行,导致高度计算不对问题(计算ListView高度)
来源:互联网 发布:淘宝会员等级v6 编辑:程序博客网 时间:2024/06/01 21:41
刚遇到一个问题,如题,我有2个ListView嵌套,所以需要计算嵌套中的ListView高度,然后就发现,TextView 中的文字换行会导致高度计算有误,只算到一行,So,上网查解决方法,找到的方法都是一个
public class myTextView extends TextView { private Context context; public myTextView(Context context) { super(context); // TODO Auto-generated constructor stub this.context = context; } public myTextView(Context context, AttributeSet attrs) { super(context, attrs); // TODO Auto-generated constructor stub this.context = context; } public myTextView(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); Layout layout = getLayout(); if (layout != null) { int height = (int)FloatMath.ceil(getMaxLineHeight(this.getText().toString())) + getCompoundPaddingTop() + getCompoundPaddingBottom(); int width = getMeasuredWidth(); setMeasuredDimension(width, height); } } private float getMaxLineHeight(String str) { float height = 0.0f; float screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth(); float paddingLeft = ((LinearLayout)this.getParent()).getPaddingLeft(); float paddingReft = ((LinearLayout)this.getParent()).getPaddingRight();//这里具体this.getPaint()要注意使用,要看你的TextView在什么位置,这个是拿TextView父控件的Padding的,为了更准确的算出换行 int line = (int) Math.ceil( (this.getPaint().measureText(str)/(screenW-paddingLeft-paddingReft))); height = (this.getPaint().getFontMetrics().descent-this.getPaint().getFontMetrics().ascent)*line; return height;}}
基本找到所有资料都是以上的代码,并不知道原作者到底是谁,自定义TextView计算高度,但是我用了之后发现有几个问题
一、当TextView没有占据一行时,显示会不全,也就是TextView左边或者右边还有控件占据了宽度,那么就会有部分数据不显示
二、没有考虑文本中含有\n换行符,计算行数有误
三、没有计算TextView本身的Padding
四、获取屏幕密度方式有误,使用以下方法强转是有风险的,且方法已经过时
float screenW = ((Activity)context).getWindowManager().getDefaultDisplay().getWidth(); float paddingLeft =
解决办法就是当你的TextView旁边还有其他控件占据宽度时,把TextView的宽度定死,或使用weight,是TextView与其他View按比例分配宽度。
修改后的版本
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(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; }}
如果有更好的解决办法,或代码中有忽略的问题,bug请留言。
另,可能有人会问RelativeLayout怎么办,我想说,计算ListView高度如果有RelativeLayout,那么是计算不了的,估计只能再次重写RelativeLayout…
0 0
- 自定义TextView,解决文字换行,\n换行符换行,导致高度计算不对问题(计算ListView高度)
- iOS NSString 没有去除首尾空格,换行符,空字符--导致UIlabel不能正确计算换行后的动态高度
- label自动换行并且计算其高度
- textview文字对齐换行问题
- 动态计算UILabel的高度,宽度,自动换行
- iOS-textView文本换行高度自动适应
- iOS-textView文本换行高度自动适应
- 自定义TextView,解决计算listView中item高度的时候,如果其中的TextView字数超过一行,只计算到一行高度的问题
- edittext 随文字换行 而高度增加
- [Visio 2007]解决 “类图”调整宽度后,换行的文字溢出的问题(如何调整“类图”的高度?)
- Textview解决换行混乱问题
- Textview解决换行混乱问题
- overflow解决float浮动后高度自适应问题 即换行
- 通过自定义TextView,拉伸每行解决自动换行文字排版参差不齐问题
- 文本高度与换行
- Android TextView 解决文字换行排版
- 自定义控件解决android中TextView中英文换行问题
- 使用Xlistview时TextView自动换行或ScrollView嵌套Listview高度显示不全
- 声明的意义
- C语言OJ项目参考(2747) 进制转换
- 线程(一)
- Android Activity启动流程
- takephoto
- 自定义TextView,解决文字换行,\n换行符换行,导致高度计算不对问题(计算ListView高度)
- Git常用操作总结
- 第十一周 日期算星座
- ubuntu的sh文件编程(二)
- Android 系统构架
- 线程(二)
- oj第十一周训练——日期妙算星座
- C++11 lambda
- iOSTableViewCell高度自适应