2

Maybe I'm not entering the right keywords, but I'm not finding an answer. I want to know what the dimensions of a TextView would be if I were set it with a certain string. However, I want to know before everything gets laid out in the activity.

My TextView has a fixed width and a variable height. I can get the height like this:

myTextView.setText(myString);

// ... UI gets laid out ...

myTextView.getHeight()

I want to change the width of the TextView if the height gets past a certain point. (But not before then.) And rather than waiting until after the UI gets laid out, I want to know beforehand what the height would be if it had myString and then change the width if I needed to.

I looked at the Layout class but I couldn't figure out what to do. I wonder if it might have something to do with overriding the TextView's onMeasure but I really don't know how to attempt that. Any help is appreciated.

Update

Thanks to both @user3249477 and @0xDEADC0DE for their answers. I'm marking @user3249477's answer as the solution for now (although since I need multiple resizes of the view I'm not sure about repeatedly turning the visibility on and off) but also +1 to @0xDEADC0DE for giving me the keywords I needed to further look into this problem.

I need to do more research and testing on this. Here are some links that I have found helpful so far:

OnLayoutChangeListener:

measureText() and getTextBounds():

Overriding onSizeChanged of the parent view also looks intriguing: https://stackoverflow.com/a/14399163/3681880

Community
  • 1
  • 1
Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
  • I would now use a `StaticLayout` to approach this problem. See [this answer](http://stackoverflow.com/a/41779935/3681880). – Suragch Feb 07 '17 at 03:04

2 Answers2

2

You could do it without overriding. If you get the TextViews Paint with getPaint(), you can use measureText(string) the get the minimal with of the TextView when it is drawn with that Paint. I looks like this:

TextView textView = new TextView(this);
float textWidth = textView.getPaint().measureText("Some Text");

Update
To get the height, you can call getTextBounds() on the Paint object like this:

    String text = "Some Text";
    Rect textBounds = new Rect();
    textView.getPaint().getTextBounds(text, 0, text.length(), textBounds);
    float height = textBounds.height();
    float width = textBounds.width();
0xDEADC0DE
  • 2,453
  • 1
  • 17
  • 22
  • This returns the text width, while OP asked for the height of the TextView. – Simas Jan 16 '15 at 14:43
  • The problem with your update is, that it crams all the text into a single line. So height is only the height of the font. – Simas Jan 16 '15 at 15:09
2

Set your TextView to invisible:

android:visibility="invisible"

and measure it. Once you're done set it to visible:

TextView myTextView = (TextView) findViewById(R.id.text);
final int maxHeight = 500;
myTextView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
    @Override
    public void onLayoutChange(View v, int left, int top, int right, int bottom,
                               int oldLeft, int oldTop, int oldRight, int oldBottom) {
        v.removeOnLayoutChangeListener(this);

        LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) v.getLayoutParams();
        Log.e("TAG", "H: " + v.getHeight() + " W: " + v.getWidth());

        if (v.getWidth() > maxHeight) {
            params.width += 100;
            v.setLayoutParams(params);
        }
        v.setVisibility(View.VISIBLE);
    }
});
Simas
  • 43,548
  • 10
  • 88
  • 116