Android lineHeight vs lineSpacingExtra - android

can I know what is the difference between lineHeight and lineSpacingExtra in android xml. I tried to compare both, but I got the different result (I need the lineHeight function, however it is only supported in API 28).
Here is part of my code:
left:
android:textSize="14sp"
android:lineSpacingExtra="6dp"
right:
android:textSize="14sp"
android:lineHeight="20dp"
Result:
Any solution for this?
Thank you.

You mentioned you want to set lineHeight in pre-API 28, an alternative approach would be to just set a small lineSpacingExtra / lineSpacingMultiplier value (as you have shown). Otherwise, there are many solutions to setting a line height yourself in this related question.
I'll briefly cover the differences below, with my summary and the official documentation.
android:lineHeight is the total height of each line. This includes the text, as well as any padding on the top and bottom.
Explicit height between lines of text. If set, this will override the values set for lineSpacingExtra and lineSpacingMultiplier.
android:lineSpacingExtra is the additional spacing added after each line of text (except the last one).
Extra spacing between lines of text. The value will not be applied for the last line of text.
Finally, you may be interested in android:lineSpacingMultiplier. This is similar to lineSpacingExtra, but with a multiplier value of the current height (e.g. 1.2) instead of a fixed value.
Extra spacing between lines of text, as a multiplier. The value will not be applied for the last line of text.
Further information (besides the included quotas) is available in the TextView documentation.

MaterialTextView (MTV) includes the ability to set the android:lineHeight.
And if you use the app: prefix, it is backwards compatible until SDK-Version 21.
Btw., under some circumstances (i believe its depending on your style, but am not sure about it), standard TextViews are automatically replaced with MTVs. (Check your LayoutInspector, you might already use them without knowing it)
In case you're still wondering about the differences, there's an excellent talk by the android team about text in general; which should solve your question at ~16:50.

android:lineHeight defines Explicit height between lines of text. while android:lineSpacingExtra defines Extra spacing between lines of text
you can read more android_documentation_for_text_arributes

android:lineHeight
is used to specify the total height for single line of text.
android:lineSpacingExtra
is used to add extra spacing between 2 lines of text in addition to the default line height used by android.
In order to replicate lineHeight functionality with API level < 28, set the lineSpacingMultiplier to 0 and set the lineSpacingExtra to the lineHeight that you want to use
android:lineSpacingMultiplier="0"
android:lineSpacingExtra="<enter line height value here in dp>"

Related

Different TextView height when not all lines have content

I have a TextView with lines = 2. I get a different result in the height of the TextView if I set a short text and only 1 line shows up, or I set a longer text and 2 lines show up. This seems to be an issue with the onMeasure function of TextView. In the code I can see that first the height of the Layout is calculated, and then a line height is added for each blank line. Javadoc notes the following:
Note that 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.
These TextViews are used in a horizontal RecyclerView where I need each list item to be the same height, that's why I set the lines fixed to 2. But apparently that doesn't make it the same height. How can this be fixed?
Some extra info regarding the TextView:
Font: Helvetica Neue Lt Std Bold
Text size: 18 sp
Lineheight: 32 sp
Either it has something to do with the lineheight not being used in the calculation of getLineHeight or Layout. Or something with the font itself. Edit: it's definitely something with the font because lineheight + roboto doesn't create this issue.
Here you can see the difference in height:
And here the TextViews have the same height because they all have the same number of lines.

lineSpacing in Jetpack Compose

Is there a way to achieve lineSpacing in Jetpack Compose? Similar to normal Android's lineSpacingExta and lineSpacingMuliplier?
I'm aware there is lineHeight in Text and TextStyle, but that is not the same thing. Line Height specifies how big each line should be, not the space between a line and the next one.
For example, line height applies to the last line, while line spacing would not, because there is no like after it

Android text is cut off on a fixed height TextView

Consider this layout:
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="160dp"
android:textSize="20sp"
android:text="Apple Inc. is an American multinational technology company headquartered in Cupertino, California, that designs, develops, and sells consumer electronics, computer software, and online services."
android:ellipsize="end"
android:gravity="top"/>
What I want the TextView to do is to figure out how many lines it can fit in 160dp and places three dots if room is not enough. However the text is cut off instead:
How can I achieve the above behavior? I assume I can do it by just specifying some attribute on the layout resource file. Thanks.
There's no way to achieve this by simply specifying attributes on the layout resource file.
If you look at the setEllipsize() method in TextView, you'll see that it says:
Causes words in the text that are longer than the view's width to be ellipsized instead of broken in the middle. You may also want to setSingleLine() or setHorizontallyScrolling(boolean) to constrain the text to a single line. Use null to turn off ellipsizing. If setMaxLines(int) has been used to set two or more lines, only TextUtils.TruncateAt.END and TextUtils.TruncateAt.MARQUEE are supported (other ellipsizing types will not do anything).
From that documentation, you can see that ellipsis in TextView is actually highly dependent on two factors: view width and number of lines.
As such, I recall that an ellipsis might not show up for a TextView if it doesn't know the maximum number of lines that your TextView can have.
So for your intended behavior, this isn't possible because you're depending on the View's height instead. You want to use a specific height then have a TextView calculate the amount of lines that can be shown within that height. Finally, if the amount of lines needed is greater than the amount shown, you want to show ellipses.
That's... not possible with how the ellipses in TextView is coded. It simply wasn't meant for that.
Therefore, if you want this behavior, you need to either:
Create a custom TextView for your specific ellipses implementation
Manually calculate the amount of lines visible, then use setMaxLines() on that TextView
For the second option, you can calculate this by using the TextView methods getHeight() and getLineHeight().
For example:
textview = (TextView) findViewById(R.id.exampleTextView);
textview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
final int maxLines = textview.getHeight() / textview.getLineHeight();
textview.setMaxLines(maxLines);
}
});
In my example, I'm doing this inside a ViewTreeObserver to avoid getHeight() calling a size of 0.
The second option should be able to get the behavior you want, but if you want this for every TextView, you should consider creating a custom TextView instead.
Set the layout_gravity on the TextView to fill

Android elevation and setElevation not the same effect

I noticed when I use elevation property in xml and set it to 4dp, I get a normal shadow. When I use setElevation(4) in java, I get less of a shadow than the xml property does. How can I fix that?
The answer given by Anton Kovalyov is almost correct, but it is actually the other way around. To get the correct elevation you need to convert your dp to pixels and feed it into setElevation, so the correct answer looks like this:
setElevation(4 * context.getResources().getDisplayMetrics().density);
setElevation takes a pixel value. User TinTran's comment is correct.
According to android documentation setElevation()
Sets the base elevation of this view, in pixels.
You need to convert pixels to dpi:
setElevation(4 / context.getResources().getDisplayMetrics().density);
That is because java use pixel. so you have to convert it into dp
you can use this :
(int)TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 4, getResources().getDisplayMetrics())

TextView onDraw - Drawing Lines

I would like to draw vertical lines between Numbers/Letters in my TextView. So it should look similar to
A|B|C|D
without the use of the | character and use drawLine() instead.
I am trying to do it using the width of the TextView and assuming the centre of each character will find itself at , 1/8, 3/8, 5/8, 7/8 of the TextView width for this example. However the lines dont line up as they should.
Not sure whats not working, help appreciated.
I am trying to do it using the width of the TextView and assuming the centre of each character will find itself at , 1/8, 3/8, 5/8, 7/8 of the TextView width for this example.
That's your problem. For starters, you haven't specified that you're using a mono-spaced font. If you're not, then the letters won't be evenly distributed. Even if you are using a mono-spaced font, likely the padding at the beginning (and possibly end) of the TextView are going to offset things. I can't remember exactly how TextView measures things, but I suspect looking at actual left padding value would be a good start to find the left padding. If you want to use this with a variable width font, you'll want to use something like Paint.measureText to measure the width of the characters.
Once you have all that, you can add the width of the character(s) to the left padding to find the position to place each line.

Categories

Resources