Android 在渲染到布局之前获取文本视图的高度
在将textview呈现到布局之前,在设置文本的位置计算textview高度时,找不到任何好的解决方案。请提供任何帮助2个解决方案 最初使用了解决方案1,后来找到了解决方案2。两种方法都有效,这是你真正喜欢的 重要的是要确保所有尺寸都正确,因为在sp或px中混合字体大小会根据您测试的屏幕产生很大的差异 一个非常基本的示例项目可以在 解决方案1使用TextView和MeasureSpec 原始问题的主要问题是下面方法中的TextView应该配置为我们的TextView,它应该呈现给布局。我认为这个解决方案对许多面临这个问题的人来说是有价值的Android 在渲染到布局之前获取文本视图的高度,android,textview,Android,Textview,在将textview呈现到布局之前,在设置文本的位置计算textview高度时,找不到任何好的解决方案。请提供任何帮助2个解决方案 最初使用了解决方案1,后来找到了解决方案2。两种方法都有效,这是你真正喜欢的 重要的是要确保所有尺寸都正确,因为在sp或px中混合字体大小会根据您测试的屏幕产生很大的差异 一个非常基本的示例项目可以在 解决方案1使用TextView和MeasureSpec 原始问题的主要问题是下面方法中的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);
解决方案2使用TextPaint和StaticLayout
这个方法依赖于TextPaint和StaticLayout,它还提供了到目前为止我测试过的所有API级别的可靠结果。注意尺寸单位;所有都应该以像素为单位
资料来源:
从support_ms answer中,有一个更简单的方法,它只将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();
}
@support_ms的回答很好,但我不确定创建一个新的TextView并计算出所有这些输入参数的意义,因为您可以先格式化TextView,然后只使用一个参数调用静态方法,
TextView
本身
另外,我不确定为什么一个参数被标记为deviceWidth
,我只是使用Textview
本身的宽度。我的是match_parent
,我想任何TextView
包含wrap_内容的都可能根本不起作用。但这就是你得到的
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();
}
这是我的简单解决方案,它可以在喷漆前得到尺寸
在渲染之前获取文本视图的行
这是我基于上述想法编写的代码。这对我有用
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;
}
注意:此代码也必须为屏幕上的real textview设置
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.tv_size_14sp));
您试图做的事情可能有问题。如果将高度设置为某个值(如60dp),则可以,但如果将其设置为“包裹内容”,则高度将取决于屏幕大小。因此,您可能希望以编程方式(用Java代码)创建textview。我正在创建电子书阅读器,为此,我应该知道textview的高度文本适合它的大小。如果您将其设置为“wrap_content”,它将根据其内容展开。如果您想确保用户不应垂直滑动,则可以查看viewflipper、viewpager等。您是否检查了此[问题]()@MobileListrici文本中有可扩展文本和不同字体,我无法计算一页有多少文本足够。这就是为什么我将文本按空格分割,添加每个元素后,它应该检查textview是否超过显示高度。为此,我应该知道textview的高度,并在每次添加textview之前进行检查如果文本包含任何将以显示的文本视图大小换行的行,则MeasureSpec.AT_最为重要。为什么此处顶部填充为0?@treesareverywhere不重要。这只是为了我的案子,我试过了,几乎奏效了。但是,最后一行文本被截断。我试着测试这个,在里面放了很多很长的乱七八糟的单词,超过20个字符,行被截断的数量增加了。我只能假设这个测量的高度没有考虑到下一行的单词溢出。因此,这个计算的高度小于实际渲染的高度,随着字数的增加和文本的加长,差异越来越大。@Distribution我应该使用EditText makeMeasureSpec或inflate上的EditText设置。至少对于单行文本视图来说,这个设置非常有效。(这就是我需要的)。请注意,由于设备的实际像素宽度通常是已知的(它通常用于应用程序的其他部分),并且变量“wm”未使用,因此只有这段代码的最后四行就足够了。伟大的工作起来很有魅力。:)令人惊叹的!谢谢你,好心的先生!这个屏幕宽度方法是什么?这个方法在其他SO答案中可用。为了清晰起见,我添加了这个方法。
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, context.getResources().getDimension(R.dimen.tv_size_14sp));