Getting height of text view before rendering to layout
2 solutions
Used solution 1 at first and found solution 2 later on. Both work, it's really what you prefer.
Important is to make sure you got all the dimensions right since mixing font sizes in sp or px will give quite a difference depending on what screen you test on.
A very basic example project is available at https://github.com/hanscappelle/SO-3654321
Solution 1 using TextView and MeasureSpec
Main issue with original question is TextView in below method should be configured as our TextView which should be rendered to layout. I think this solution is valuable for many people who faced this problem.
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();
}
And an example of how to use this:
// 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);
Solution 2 using TextPaint and StaticLayout
This method relies on a TextPaint and StaticLayout which also gives reliable results on all API levels I've tested so far. Pay good attention to units of dimensions; all should be in pixels!
Source: 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();
}
Getting Height of TextView before render it in layout
I have to know the size of textViewA's height value to make show the background. How to do it?
We can not get the TextView's height directly, because the TextView might not even been measured by that time.
If you really want to get the textViewA's height please try the following code
ViewTreeObserver vto = textViewA.ViewTreeObserver;
vto.GlobalLayout += (sender, args) =>
{
myTextViewHeight = textViewA.Height;
};
But you measure the textViewA in the FrameLayout. When you get the "myTextViewHeight" your layout has been measured. You will still get the 0 height before you add it in the FrameLayout
As a workaround
you can set "textViewA.Height" before you add in FrameLayout
you can add your background as default:
frame.AddView(textViewA, LayoutParams.MatchParent, LayoutParams.WrapContent);
frame.AddView(background);
By the way, if you just need to set the background of your tablerow ,Adding textview in your tablerow with background or just setting the tablerow background could be a better choice.
How to get line count of textview before rendering?
final Rect bounds = new Rect();
final Paint paint = new Paint();
paint.setTextSize(currentTextSize);
paint.getTextBounds(testString, 0, testString.length(), bounds);
Now divide the width of text with the width of your TextView to get the total number of lines.
final int numLines = (int) Math.ceil((float) bounds.width() / currentSize);
currentSize : Expected size of the view in which the text will be rendered. The size should not go beyond the screen width.
Related Topics
How to Change Letter Spacing in a Textview
Add Github Library as Dependency to Android Studio Project
Ndk - How to Use a Generated .So Library in Another Project
Android Programming: Where to Start for Creating a Simple File Browser
Lame Mp3 Encoder Compile for Android
Android: Sample Code to Connect to Vpn in Android 4.0 Using Vpnservice API
Oniabpurchasefinished Never Called
Configure Eclipse to Use Signed Keystore
Android - Wake Up and Unlock Device
Android Layout Animations from Bottom to Top and Top to Bottom on Imageview Click
Android Recyclerview: Change Layout File List to Grid Onoptionitemselected
Android: Looking for a Drawarc() Method with Inner & Outer Radius
How to Give Notifications on Android on Specific Time
Android Translate Animation - Permanently Move View to New Position Using Animationlistener
Android: Get Facebook Friends List