如何为 Android 正确设置行高?

我是一名用户体验架构师,与一个 Android 开发团队合作,他们大多是初级开发人员。我们在安卓系统中有正确设置行高的问题。

我们使用的材料设计规范作为我们的应用程序的指南。特别是,您可以在这里看到行高规格:

Https://material.google.com/style/typography.html#typography-line-height

让我们以身体2为例。说明书上说这个类型是13sp 或14sp,前导(行高度-同样的东西)应该是24dp。

这就是问题所在: 这些开发人员告诉我,在代码中没有这样的方法来设置行高。相反,他们告诉我测量两行文本之间的距离,并给他们测量-让我们说它是4dp。对于我们使用的每种文本样式,他们都希望这样做。

我们使用一个草图 > 齐柏林飞艇流程的规格。

对我来说,能够创建一个字体样式(在代码中很容易就是 class/style)是13sp,24dp 开头,而不能设置开头,而是必须添加第三个度量到混合中,这似乎很奇怪。在 Sketch 或 Zepelin 没有这样一个“行与行之间”的度量标准

这真的是这样做的吗,还是有一个合适的方法来设置行高?

98730 次浏览

Here's a way to do it programatically.

public static void setLineHeight(TextView textView, int lineHeight) {
int fontHeight = textView.getPaint().getFontMetricsInt(null);
textView.setLineSpacing(dpToPixel(lineHeight) - fontHeight, 1);
}


public static int dpToPixel(float dp) {
DisplayMetrics metrics = getResources().getDisplayMetrics();
float px = dp * (metrics.densityDpi / 160f);
return (int) px;
}

Here's React Native's solution: add a span that adjusts the line height https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan.java

My design colleagues use line height excessively and its a pain that it never looks right after rending in-app.

I'll be planning on making a custom TextView class that takes an arg by XML and will post it here after.

I'll explain this from Android Developer perspective.

Line height usually means text size + "padding" top/bottom.

So, if your designer write line height 19sp and text size 15sp, it means you need to have extra padding 4sp.

19sp - 15sp = 4sp.

To implement it in your layout, use lineSpacingExtra attribute.

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:lineSpacingExtra="4sp"
android:fontFamily="sans-serif"
tools:text="StackOverflow is awesome"
/>

Another way to achieve line height is using scale. For example, 1.2. It means, the spacing is 120% of the text size.

In example above, the line height is 19sp and the text size is 15sp. If we translate it into scale, it become.

19/15 = 1.26

To implement it in your layout, use the lineSpacingMultiplier attribute.

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="15sp"
android:lineSpacingMultiplier="1.26"
android:fontFamily="sans-serif"
tools:text="StackOverflow is awesome"
/>

Since API 28 we now have lineHeight

<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Lorem ipsum dolor sit amet"
app:lineHeight="50sp"/>

If you are using a style don't forget to remove the app:

<style name="H1">
<item name="android:textSize">20sp</item>
<item name="lineHeight">30sp</item>
</style>

Or in code

TextView.setLineHeight(@Px int)
lineHeight = height * multiplier + extra

So if you set multiplier = 0 then you can get line-height to be the same as an extra.

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="14sp"
android:lineSpacingMultiplier="0"
android:lineSpacingExtra="24sp"
/>

2022

This works for me pre API 28 and above:

<style name="whatever">
<item name="android:lineHeight" tools:targetApi="p">28sp</item>
<item name="lineHeight">28sp</item>
</style>

Adding target api for "android:lineHeight" to make sure it doesn't override "lineHeight" seems to do the trick.

following this answer
https://stackoverflow.com/a/52735596/8668620
and add

android:includeFontPadding="false"

too

enter image description here Hello, We can add this like that: app:lineHeight="42dp"