I have a rectangular tile, and I want to fit an image and some text into it. The image must not overlap the text, and the sizes of the image and the text can vary.
The process must be hand-coded, since we have to fine-tune it according to our client's needs.
I tried the approach of first measuring the rendered text bounds using getTextBounds()
or measureText()
and then adapting the font size and the image size so they don't overlap.
This works fine if the text is only on one line.
But if TextView
wraps the text onto multiple line, I cannot predict the text bounds, since I don't know where TextView
would insert the automatic line breaks.
How can I find out the positions in the text where TextView
inserts an automatic line break?
Example: Given the text
Lorem ipsum dolor sit amet
which would be rendered as
| Lorem ipsum |
| dolor sit amet |
I need a function that converts
Lorem ipsum dolor sit amet
to
Lorem ipsum \ndolor sit amet
TextView (Layout object) has some useful functions for what you are trying to accomplish:
http://developer.android.com/reference/android/text/Layout.html
take a look at:
getLineCount()
getLineEnd(int line)
You can get the substring for the TextView string based on where the character is located at each lineEnd.
You will need to use getViewTreeObserver()
to wait until the TextView is drawn before you can call these and get useful information from them.
Alternatively, you can build a custom TextView that might provide the data through built-in methods or by adding a listener to it. An example of a custom TextView that modifies text size is here:
android ellipsize multiline textview
I've used that and did similar modifications (like what you are trying to do).
You'd probably want to wrap this logic into a custom view (overriding onSizeChanged()
) but you can use the Layout
class to check where each line ends:
textView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Remove immediately so it only fires once
textView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
// View should be laid out, including text placement
final Layout layout = textView.getLayout();
float maxLineWidth = 0;
// Loop over all the lines and do whatever you need with
// the width of the line
for (int i = 0; i < layout.getLineCount(); i++) {
maxLineWidth = Math.max(maxLineWidth, layout.getLineWidth(i));
}
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With