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
Related
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.
When I create a line chart with values for each point, the values on the chart overlap the line, as shown in the screenshot. Is there a function to add padding to the values to raise them up so that this doesn't happen? I've looked all over the place for an answer to this or even someone else having the same issue and haven't found what I'm looking for.
My current chart:
I figured it out.
Based on this line in the source code:
int valOffset = (int) (dataSet.getCircleRadius() * 1.75f);
The padding is calculated based on the radius of the circle on the line, so my solution is to increase the size of the circle, set the outer radius to be transparent, and set the hole color to be the same as the line, which accomplishes what I want. This may not work for everyone, depending on what you're trying to do, but it worked in my case.
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>"
I'm trying to draw text using Canvas and have found that using StaticLayout would take care of the line breaks automatically. I also want to limit its height so that when text is too long it would be ellipsized, but the size of text container is dynamic. I can easily apply the width to StaticLayout, but cant find a way to do height.
I tried to utilize TextUtils.ellipsize(), but having issue to get the spacing between lines.
PerracoLabs has the right answer but, as CheokYanCheng stated, the calculation of the maximum number of lines is off (although it may yield the correct result many if not most of the time).
A maximum height cannot be specified for a StaticLayout except indirectly by specifying the maximum number of lines. Ellipsis is tied to the maximum line count anyway, so determining the maximum number of lines for a specific height to back into a solution is the way to go. So, how do we determine the appropriate maximum line count so that a fixed-size StaticLayout with ellipsis can be created as PerracoLabs has explained.?
If the text has no spans that effect the height any of the lines of text then a simply calculation can determine the maximum number of lines that will fit into a StaticLayout before ellipsis.
The following Kotlin function will determine how many lines of text will fit into a view that has a fixed height and width. It is assumed that each line of a StaticLayout has a set height (no height-effecting spans). The top line has the same height of other lines but it is augmented by a top padding. The bottom line has a bottom padding added to it.
private fun getMaxLines(maxHeight: Int): Int {
// Build a dummy StaticLayout to get the internal measurements.
return makeStaticLayout("", width, 1).run {
val lineHeight = getLineBottom(0) - getLineTop(0) + topPadding - bottomPadding
(maxHeight - topPadding - bottomPadding) / lineHeight
}
However, if the text contains a span that changes the height of one or more lines then the only way to calculate the maximum number of lines is through the creation of the static layout that holds the entire text (no ellipsis) followed by an inspection of the lines within the layout to determine how many complete lines have fit. A new StaticLayout can then be created with the calculated maximum lines determined from the inspection.
The following Kotlin function will calculate the maximum lines by inspecting the StaticLayout for the last full line that is present.
private fun getMaxLinesByInspection(staticLayout: StaticLayout, maxHeight: Int): Int {
var line = staticLayout.lineCount - 1
while (line >= 0 && staticLayout.getLineBottom(line) >= maxHeight) {
line--
}
return line + 1
}
I have posted a small project on GitHub as a demonstration.
Here is a screen shot of the app.
You (and #Cheok Yan Cheng) might try to make use of PagedTextView. The view is intended for Paginating text in Android.
The view partially solves the problem, i.e. reacts to dynamic size changes. As to text ellipsizing, you might achieve this by customising the algorithm I've used for measuring text in height.
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.