I have some squarish TextViews (with different dynamic sizes(I don't know them while I'm developing)) in my Application and want to set their text. But if I say TextView.setText(); the text font is pretty small. If I set TextView.setFontSize sometimes the text is not fully displayed (remember: they have a dynamic size). So my question: how can I give the text the perfect font (using the full space of the button AND being fully displayed) or make the Text squarish itself so that it fills the whole space of the TextView?
Thank You
You may use Paint.getTextBounds() like this:
int textViewWidth = textView.getMeasuredWidth();
float textSize = 1.0;
do {
textSize += 0.5
textView.setTextSize(textSize);
Paint textPaint = textView.getPaint();
textPaint.getTextBounds(text, 0, text.length(), rect);
int width = rect.width();
} while (width < textViewWidth);
textView.setTextSize(textSize - 0.5);
Looking over the documentation, it looks like you should be able to use something like this:
TextView tv = (TextView) findViewById(R.id.myTextView);
tv.setTextScaleX(tv.getWidth());
This will scale the width of your text to the width of the TextView.
I think you will need to calculate heights of the button and the text you wish to set. APIs you will need are: Paint.getTextBounds() and View.getHeight().
Related
I am new to Android.. I have a textview with size 250dp.. I am trying to calculate the text width inside it.. But I could not find any API that returns the actual content width.. Can someone help how it can be done.
Thanks in advance.
You can use the Paint object held by the TextView to measure the width of the text contents:
CharSequence text = textView.getText();
float width = textView.getPaint().measureText(text, 0, text.length());
There is also a version that measures the full bounds (left/right/top/bottom) of the text contents:
Rect bounds = new Rect();
CharSequence text = textView.getText();
textView.getPaint().getTextBounds(text, 0, text.length(), bounds);
//bounds now contains the rect of the actual text string
int width = bounds.getWidth();
The Devunwired answer is completely right.
However, it's useful the reader to know that the text width measure in pixels don't need to be linked with any real content of a TextView or EditText and isn't restricted to the view widht, so one can simulate if a determinated text fits well in the view before set the view with a text.
Besides, if one uses the whole string you don't need to specify a initial index and a final index (exclusive).
So one can write
float width = textView.getPaint().measureText("my favorite fruit is a banana");
It works smoothly
There is no API for this.first you have to find the text size and find lenth of string.finally multipl both you will get width of text in textview.
I am working on Book application.Let me give you all concept
There is one big text and have Multiple Textviews as per length of the Text.
I have to show one text(part of big text) which appear in the screen(No scroll).if other text not visible to the user,than other text should appear in the other textview (Next page).
as i googling , I can't find a way to take length of the text which is appear in the one textview (one page).So I can take other text in the other page
I have attached some image for clear the concepts.
Please suggest me. What can i do for that? Thank in advance
ok there are three solutions
if you calculate screen sizes and use sizes like small medium and large.
and you just divide your data and set in textview.
Get number of lines of text that will fit on the screen than Measure how much text will fit across the TextView. Calculate Total amount of text to fill the TextView is approximately.
private void TextMeasure(String text,
TextView tvl, TextView tvr) {
int linesPerScreen = tvl.getHeight() / (tvl.getLineHeight() + (int) tvl.getLineSpacingExtra());
Paint paint = tvl.getPaint();
int textWidth = paint.breakText(text, 0, text.length(),
true, tvl.getWidth(), null);
int totalText = textWidth * linesPerScreen;
String leftText = text.substring(0, totalText);
String rightText = text.substring(totalText,
text.length());
tvl.setText(leftText);
tvr.setText(rightText);
}
source
probably this question help you out.
I have an Android application layout which contains a multiline TextView. When the screen is in portrait orientation, the TextView can display a different length of text to when running in landscape mode. Also when running on a small screen, the TextView can display a different length of text to when running on a larger screen.
Is there any way I can check if the text fits or will be truncated? Or is there any way I can check if the TextView if full?
The problem is the TextView can potentially contain a different number of lines, depending on whether it is landscape, portrait, small screen, large screen, etc.
Thank you for your advice,
Best regards,
James
These answers didn't work very well for me. Here's what I ended up doing
Paint measurePaint = new Paint(myTextView.getPaint());
float pWidth = measurePaint.measureText("This is my big long line of text. Will it fit in here?");
float labelWidth = myTextView.getWidth();
int maxLines = myTextView.getMaxLines();
while (labelWidth > 0 && pWidth/maxLines > labelWidth-20) {
float textSize = measurePaint.getTextSize();
measurePaint.setTextSize(textSize-1);
pWidth = measurePaint.measureText("This is my big long line of text. Will it fit in here?");
if (textSize < TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_SP, 7,
getContext().getResources().getDisplayMetrics())) break;
}
myTextView.setTextSize(TypedValue.COMPLEX_UNIT_PX, measurePaint.getTextSize());
I'm not saying this will work for every situation as I'm certainly cutting corners here, but the general idea is to measure the text with the textview's paint and keep shrinking it until it will fit inside the textview.
I have found a "cheeky" solution to the problem of measuring the height of the text in a MULTILINE TextView :-
//Calculate the height of the text in the MULTILINE TextView
int textHeight = textView.getLineCount() * textView.getLineHeight();
if (textHeight > textViewHeight) {
//Text is truncated because text height is taller than TextView height
} else {
//Text not truncated because text height not taller than TextView height
}
However this solution has some caveats :-
Firstly regarding getLineHeight() , markup within the text can cause individual lines to be taller or shorter than this height, and the layout may contain additional first- or last-line padding. See http://developer.android.com/reference/android/widget/TextView.html#getLineHeight()
Secondly , the application needs to calculate the actual height of the TextView in pixels , and (in the case of my layout) it might not be as simple as textView.getHeight() , and calculation may vary from one layout to another layout.
I would recommend avoiding LinearLayout because the actual pixel height of the TextView can vary depending on text content. I am using a RelativeLayout (see http://pastebin.com/KPzw5LYd).
Using this RelativeLayout, I can calculate my TextView height as follows :-
//Calculate the height of the TextView for layout "http://pastebin.com/KPzw5LYd"
int textViewHeight = layout1.getHeight() - button1.getHeight() - button2.getHeight();
Hope that helps,
Regards,
James
Basically, you need to calculate the size of your textview and the size of your text when the orientation mode changed. Try ViewTreeObserver.OnGlobalLayoutListener to do so.
Inside the change orientation method:
main_view.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
main_view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
//Calculation goes here
int text_size = getTextSize(text_view.getText().toString());
int text_view_size = text_view.getLayoutParams().width;
//Compare your text_size and text_view_size and do whatever you want here.
}
});
Here is the code of calculate the text_size:
private int getTextSize(String your_text){
Paint p = new Paint();
//Calculate the text size in pixel
return p.measureText(your_text);
}
Hope this help.
For checking whether a multiline (or not) TextView is going to be truncated, check this post.
Or, have you looked into using a scrolling textview? (marquee).. where the text will scroll by (horizontally, animated) if it is too long for a given width?
Here is an example TextView in a layout file, that has some of these characteristics:
<TextView
android:id="#+id/sometextview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"
android:freezesText="true"
android:textColor="#808080"
android:textSize="14sp"
android:text="This is a long scrolling line of text.. (etc)"/>
This extension function in Kotlin worked for me, just make sure to call it when the view is already laied out, e.g. view.post() is a good place for me;
/**
* Make sure to call this method only when view layout is finished, e.g. view.post() is a good place to check this
*/
fun TextView.isTruncated() = (lineCount * lineHeight) > height
Usage
textView.post {
if(isTruncated()) {
// Do something
}
}
Just check textView.getLineCount(), if line count > 1 then your text is multiline
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 layout that looks something like this:
[TextView 1] [TextView 2]
[ TextView 2 spill-over ]
Essentially, I need the contents of TextView 2 to wrap to the next line, but start where TextView 1 starts. I was thinking that if I knew how much text would fit into TextView 2 before it runs out of space on line one, I could take the rest of the text and put it in another TextView below the first two. So I need to measure how much text will fit into a TextView (which can be tricky because as far as I can tell, Android will try to break the text in a TextView at a good location so that it won't break a word in the middle if it can be avoided) or I need a new idea on how to lay this out.
Any help would be greatly appreciated.
Thanks in advance,
groomsy
Unfortunately, Paint.breakText didn't return the exact same result as in was seen in my two-line TextView.
However, this worked
int numChars = textView.getLayout().getLineEnd(1);
(use numberOfLines - 1 as the parameter to it)
Ref
http://developer.android.com/reference/android/text/Layout.html#getLineEnd(int)
Set individual lines of TextView to different width
You can create a Paint object with TextView2's text size and use breakText() to measure how many characters will fit in your TextView2's width.
(This is untested code - might need some slight modifications)
String textToBeSplit = arbitraryText; // Text you want to split between TextViews
float textView2Width = somehowGetItsWidth; // TextView2's width
float myTextSize = textView2.getTextSize();
Paint paint = new Paint();
paint.setTextSize(myTextSize); // Your text size
int numChars = paint.breakText(textToBeSplit, true, float textView2Width, null);
numChars tells you how many characters in textToBeSplit will fit in TextView2's width, enabling you to split it between your views.
You don't need two TextViews in order to do this, you should always use as few views as possible and you can use a spannable in order to have two styles for the same textview.
For example with :
TextView tv = (TextView) findViewById(R.id.textview);
SpannableString text = new SpannableString(myString);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myStyle), 0, 5, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
text.setSpan(new TextAppearanceSpan(getContext(), R.style.myNextStyle), 6, 10, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
tv.setText(text, TextView.BufferType.SPANNABLE);