无法找到任何好的解决方案计算textview height 在将 textview渲染到布局之前将文本设置为的位置。请帮忙
答案 0 :(得分:65)
首先使用解决方案1,稍后找到解决方案2。两者都有效,这真的是你喜欢的。
重要的是要确保你拥有所有尺寸,因为在sp或px中混合字体大小会产生很大差异,具体取决于你测试的屏幕。
https://github.com/hanscappelle/SO-3654321
提供了一个非常基本的示例项目原始问题的主要问题是下面的方法中的TextView应该被配置为我们的TextView,它应该被渲染为布局。我认为这个解决方案对于许多遇到这个问题的人来说很有价值。
public static int getHeight(Context context, CharSequence text, int textSize, int deviceWidth, Typeface typeface,int padding) {
TextView textView = new TextView(context);
textView.setPadding(padding,0,padding,padding);
textView.setTypeface(typeface);
textView.setText(text, TextView.BufferType.SPANNABLE);
textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, textSize);
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
textView.measure(widthMeasureSpec, heightMeasureSpec);
return textView.getMeasuredHeight();
}
以及如何使用它的一个例子:
// retrieve deviceWidth
int deviceWidth;
WindowManager wm = (WindowManager) textView.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
Point size = new Point();
display.getSize(size);
deviceWidth = size.x;
} else {
deviceWidth = display.getWidth();
}
// the text to check for
String exampleTextToMeasure = "some example text that will be long enough to make this example split over multiple lines so we can't easily predict the final height";
// some dimensions from dimes resources to take into account
int textSize = getContext().getResources().getDimensionPixelSize(R.dimen.text_size);
int padding = getContext().getResources().getDimensionPixelSize(R.dimen.text_padding);
// final calculation of textView height
int measuredTextHeight = getHeight(getContext(), exampleTextToMeasure, textSize, deviceWidth, TypeFace.DEFAULT, padding);
此方法依赖于TextPaint和StaticLayout,它还可以在我到目前为止测试的所有API级别上提供可靠的结果。要注意尺寸单位;一切都应该是像素!
来源:Measuring text height to be drawn on Canvas ( Android )
public static int method1UsingTextPaintAndStaticLayout(
final CharSequence text,
final int textSize, // in pixels
final int deviceWidth, // in pixels
final int padding // in pixels
) {
TextPaint myTextPaint = new TextPaint();
myTextPaint.setAntiAlias(true);
// this is how you would convert sp to pixels based on screen density
//myTextPaint.setTextSize(16 * context.getResources().getDisplayMetrics().density);
myTextPaint.setTextSize(textSize);
Layout.Alignment alignment = Layout.Alignment.ALIGN_NORMAL;
float spacingMultiplier = 1;
float spacingAddition = padding; // optionally apply padding here
boolean includePadding = padding != 0;
StaticLayout myStaticLayout = new StaticLayout(text, myTextPaint, deviceWidth, alignment, spacingMultiplier, spacingAddition, includePadding);
return myStaticLayout.getHeight();
}
答案 1 :(得分:12)
从support_ms回答中,有一个更简单的方法,只将TextView作为参数。
/**
* Get the TextView height before the TextView will render
* @param textView the TextView to measure
* @return the height of the textView
*/
public static int getTextViewHeight(TextView textView) {
WindowManager wm =
(WindowManager) textView.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
int deviceWidth;
if(android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2){
Point size = new Point();
display.getSize(size);
deviceWidth = size.x;
} else {
deviceWidth = display.getWidth();
}
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
textView.measure(widthMeasureSpec, heightMeasureSpec);
return textView.getMeasuredHeight();
}
答案 2 :(得分:4)
来自@support_ms的答案很好,但我不确定创建一个新的TextView并解决所有这些输入参数的问题,当你可以先格式化TextView然后只调用一个静态方法时参数,TextView
本身!
另外,我不确定为什么一个参数被标记为deviceWidth
我只使用Textview
本身的宽度。我的match_parent
是TextView
,我认为任何带有wrap_content
的{{1}}都可能根本不起作用。但那就是你得到的。
public static int getHeight(TextView t) {
int widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(screenWidth(t.getContext()), View.MeasureSpec.AT_MOST);
int heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
t.measure(widthMeasureSpec, heightMeasureSpec);
return t.getMeasuredHeight();
}
public static int screenWidth(Context context)
{
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
return display.getWidth();
}
答案 3 :(得分:0)
这是我的简单解决方案,它可以在涂漆之前获得尺寸
答案 4 :(得分:0)
在渲染之前获取TextView行
这是我的代码基于上面的想法。它对我有用。
private int widthMeasureSpec;
private int heightMeasureSpec;
private int heightOfEachLine;
private int paddingFirstLine;
private void calculateHeightOfEachLine() {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int deviceWidth = size.x;
widthMeasureSpec = View.MeasureSpec.makeMeasureSpec(deviceWidth, View.MeasureSpec.AT_MOST);
heightMeasureSpec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
//1 line = 76; 2 lines = 76 + 66; 3 lines = 76 + 66 + 66
//=> height of first line = 76 pixel; height of second line = third line =... n line = 66 pixel
int heightOfFirstLine = getHeightOfTextView("A");
int heightOfSecondLine = getHeightOfTextView("A\nA") - heightOfFirstLine;
paddingFirstLine = heightOfFirstLine - heightOfSecondLine;
heightOfEachLine = heightOfSecondLine;
}
private int getHeightOfTextView(String text) {
// Getting height of text view before rendering to layout
TextView textView = new TextView(context);
textView.setPadding(10, 0, 10, 0);
//textView.setTypeface(typeface);
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.tv_size_14sp));
textView.setText(text, TextView.BufferType.SPANNABLE);
textView.measure(widthMeasureSpec, heightMeasureSpec);
return textView.getMeasuredHeight();
}
private int getLineCountOfTextViewBeforeRendering(String text) {
return (getHeightOfTextView(text) - paddingFirstLine) / heightOfEachLine;
}
注意:此代码也必须在屏幕上为真实文本视图设置
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.tv_size_14sp));