0

I'm trying to get a textview to occupy up to 2 lines (would only be 1 line if there is only 1 word / no spaces), but be as narrow as possible.

For example:

Short

Medium
Text

Some longer
text here

Some very long text that might get very
wide but will never go over 2 lines

Any ideas on how to achieve this?

At the moment, the only way I've found is to hard code line breaks in my strings, which isn't ideal, and is resulting in a lot of duplicated strings.

Added for clarification: The layout containing the text view gets used in a recylerView, so I can't (and don't want to) constrain the width - the textview should grow as large as it needs to (and hence expand it's parent, which is set to wrap_content), but do so over 2 lines not 1.

To put it another way, a textView with fixed height and variable width, to show all the content.

Extending TextView

Ok, so I think my only option is to create a custom textview. I'm new to this, so here's the approach I'm planning:

  • Extend TextView and override onDraw();
  • split the string by the first space encountered
  • Measure widths of strings A and B
  • Get max of A and B lengths
  • split the string by the second space encountered (if exists)
  • Get max width of 2 sub strings
  • Compare to the max width from this split to the max width from the first split, and keep lowest
  • Repeat this for every space in the string, to determine which split results in the smallest overall width
  • Set the width of the TextView based on this

Does this make sense? Is there a better approach?

(Note, if I was using a fixed width font, I could use the string length/2, and step out either side from that until I hit a space and then replace that with a line break.)

Charlie Walker
  • 129
  • 1
  • 2
  • 9

2 Answers2

0

Add android:maxLines="2" to the TextView

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • but that doesn't help with a dynamic width - it doesn't force it to use the two lines as a preference over the available width. All this does is prevent it going over 2 lines – Charlie Walker Oct 22 '21 at 02:34
  • Ah, it wasn't clear that that's what you were looking for. The question itself says "wrap to max of 2 lines", and it wasn't clear you wanted more from the example. You can set a max width by using constraints in a constraint layout. Try also adding android:breakStrategy=2, which sets the line break strategy to favor equal line size. – Gabe Sechan Oct 22 '21 at 03:01
  • My above suggestion still might not make it take less than the maximum width if it would fit on 1 line though, I'm unsure. If you really need that, you're probably going to need to not use a textview and do things via a custom view. – Gabe Sechan Oct 22 '21 at 03:06
  • Sorry, maybe I should have added more detail - this is being used as an icon with a caption below it, and this layout then gets used in a horizontal recylerView. So, I can't constrain the width of the text view - it needs to be able to grow as large as it needs to, to show all the text, but to do so on 2 lines not one. – Charlie Walker Oct 22 '21 at 04:09
  • @CharlieWalker If you want it to be laid out below an icon, the constraints would be to set the left edge to the left edge of the icon and the right edge to the right edge of the icon – Gabe Sechan Oct 22 '21 at 05:27
  • that still doesn't get me the text on 2 lines. The text still grows on a single line until the TV fills the total available space before wrapping onto 2 lines. – Charlie Walker Oct 22 '21 at 15:00
  • @CharlieWalker If you really want something that specific, you're probably going to need to roll your own view. – Gabe Sechan Oct 22 '21 at 15:25
0

I finally found a way to do this in compose using
modifier = Modifier.width(IntrinsicSize.Min)

Combined with a lineLimit, this asks the view to draw "as narrow as possible", which forces the text to use 2 lines

Charlie Walker
  • 129
  • 1
  • 2
  • 9