I have a TextView, and i want to know, at runtime, if the text is to long.
The requirement that is making this tricky, and thus haven't found a solution to it, is that I DO NOT want to use ellipsize, because I do NOT want to show three dots at the end.
ideas?
thanks
to check on runtime you have to use a paint object.
doc ref: Paint.measureText(String) and TextView.getPaint()
// the code below must be run AFTER the TextView have been layout on the screen.
Paint p = textView.getPaint();
float width = p.measureText("your text here");
if(width > textView.getWidth()){
// bigger
}
TextUtils class also have some interesting methods that you might be interested, for example, the method that calculates the ellipsize: TextUtils.ellipsize(...)
Related
I am trying to calculate the height needed by a text programmatically, so I am using StaticLayout.
I was experimenting with a Label (TextView) using its paint object, to make sure the height calculated is the same as TextView's height rendered by Android.
It works good for single-line text both in Arabic and English, and works for mutli-line text in English, but Arabic height is off, it is always shorter than what Android renders.
The top height ~80 is what the TextView's height is, while the latter ~75 is the calculated height needed.
Since that it works fine in English, I guess I might need to set some other property or something, but I cannot tell what.
Following is my code, it is in C# since I am using Xamarin, but it should be clear for Android developers.
Control is TextView.
double getTextHeight(string str, double widthConstraint)
{
if (Control == null || String.IsNullOrWhiteSpace(str))
return 0;
var builder = StaticLayout.Builder.Obtain(str, 0, str.Length, Control.Paint, (int)widthConstraint);
builder.SetAlignment(Control.Layout.GetAlignment());
builder.SetIncludePad(true);
builder.SetLineSpacing(Control.Layout.SpacingAdd, Control.Layout.SpacingMultiplier);
builder.SetBreakStrategy(Control.BreakStrategy);
builder.SetJustificationMode(Control.JustificationMode);
builder.SetHyphenationFrequency(Control.HyphenationFrequency);
var staticLayout = builder.Build();
return staticLayout.Height;
}
This is the code I was missing, it is working like charm :)
builder.SetUseLineSpacingFromFallbacks(true);
builder.SetUseLineSpacingFromFallbacks(true);
but is need api 28
Is there any simple way of changing the text of a TextView in order to make it fit the view's size? Note that I do not want to truncate the text or to put an ellipsis, I want to set a different text.
For example instead of Experience: I want to use Exp: if the view is too small(where both those strings are resources).
I know that I could "avoid" this writing a custom .xml layout file for every possible screen size, but I'd like to avoid this if possible. I'm already using some different layout files, but only for situations where the layout needs some radical change to fit the size of the screen. Also in some circumstances I'd like to be able to dynamically set the text of a TextView and this can't be done via xml layout files.
I'm interested only in single-line TextViews and width.
The only way I could think of is to use a custom TextView subclass that uses a fallback text if the original text doesn't fit, but I wonder whether there is a simpler solution and, eventually, how can I reliably compute whether some text fits the TextView size or not.
You can try something like this:
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;
if( textView.getWidth() > screenWidth ) {
textView.setText("Exp:");
} else {
textView.setText("Experience:");
}
I'm not sure if you need to use getWidth() or getMeasuredWidth() so if it will not work, try second option.
I have code:
Text infoText = new Text(560, 10, mFont, "this text is too long to be in one line", activity.getVertexBufferObjectManager());
How I can set this text width(for example 200px). When text will be longer than this width it should break line and write more in next line.
I can' t find any example for this. Is it possible in Andengine gles 2 ?
I was looking around in AndEngine's code to find a solution for your problem, and I think I've found it. The method splitLines in the FontUtils class seems to be what you need.
It's arguments are: the the text you're splitting, the font to measure widths with (The font you'll be using for the text), an object that extends List<CharSequence> to save the new lines in, the type of split (AutoWrap.WORDS to split by words) and the maximum width per line.
Here's a link to the example from the AndEngine examples
https://github.com/nicolasgramlich/AndEngineExamples/blob/GLES2/src/org/andengine/examples/TextBreakExample.java
that should do it for you
I have a problem placing a textView at specified center's x and y coordinates.
Firstly, I tried to set the text in the textView, and to move the view with the width and the height of the view
from this link.
But it doesn't work, and I'd like to try something else.
I'd like to know if there is a method to get the size which a specified text will take in my textView?
I mean, I know the text and the textSize, how can I get the width and the height my textView will take?
Something like the method (NSString)sizeWithFont; for those who know iPhone dev.
Rect bounds = new Rect();
textView.getPaint().getTextBounds(textView.getText().toString(), 0, textView.getText().length(), bounds);
bounds.width() will give you the accurate width of the text in the Text View.
If your textview is called tv
tv.setText("bla");
tv.measure(0, 0); //must call measure!
tv.getMeasuredHeight(); //get height
tv.getMeasuredWidth(); //get width
More on this (updated): How to get width/height of a View
For some reason the solution of Midverse Engineer does not give me always correct results (at least on some Android versions). The solution of Sherif elKhatib works, but has the side effect of changing MeasuredWidth and Height. This could lead to incorrect positioning of the textView.
My solution:
width = textView.getPaint().measureText(text);
metrics = textView.getPaint().getFontMetrics();
height = metrics.bottom - metrics.top;
Using the TextView inner Paing class is not so hot when you have multiple lines of text and different paddings. So stop trying to reinvent the wheel. Use getMeasuredHeight and getMeasuredWidth methods after calling measure(UNSPECIFIED, UNSPECIFIED). Just don't forget to get the new values inside the post, otherwise mostly you'll get a wrong result.
tv.setText(state.s);
tv.measure(UNSPECIFIED,UNSPECIFIED);
tv.post(new Runnable() {
#Override
public void run() {
Log.d("tv","Height = "+tv.getMeasuredHeight());
Log.d("tv","Width = "+tv.getMeasuredWidth());
}
});
I have a long text so I've decided to divide it into pages, and I put a so each swipe scrolls to the next page.. The way I did it was:
NumberOfPages=text.length()/CharPerPage; //CharPerPage=500;
NumberOfPages++;
Chapters.add(text.indexOf(" ", CurrentPage*CharPerPage));
CurrentPage++;
int tmp=0;
for(int i =NumberOfPages;i>0;i--)
{
tmp =(CurrentPage*CharPerPage);
if(tmp>text.length())
{
Chapters.add(text.length());
break;
}
else
{
Chapters.add(text.indexOf(" ", tmp));
CurrentPage++;
}
}
So I divide the text into pages, and each page has 500 chars... But this isnt good since Android has different screen sizes and shapes, and line breaks arent counted so it may go beyond the screen...
So can anyone suggest a way to know how many chars are needed to fill the screen so i can make the rest of the text to another page? Thanks.
Ok here is a shot - and a rather clumsy one but in short:
*You need need to know if any give line of text will fit width-wise in your view
*You need to know how many lines you have
*You need to handle embedded newlines
so
will some text fit on any given line
private boolean isTooLarge (TextView text, String newText) {
float textWidth = text.getPaint().measureText(newText);
return (textWidth >= text.getMeasuredWidth ());
}
how many lines does your textview have:
numLinesPerPage=mTextView.getHeight()/mTextView.getLineHeight(); //not this doesn't handle special cases where you've changed the font, bolded it etc
With these two tools you could iterate through your text adding words keeping track of how many lines you have left to work with (and handle your newlines if your text contains them)
note: getHeight can't be called in constructor since it doesn't know the height yet - you could also do this in onDraw or maybe onMeasure if you have a custom control.