如何正确设置Android的行高?


76

我是UX架构师,与一群初级的Android开发人员一起工作。我们在Android中正确设置行高时遇到问题。

我们正在使用材料设计规范作为我们应用的指南。特别是,您可以在此处查看线​​高规格:

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

让我们以Body 2为例。规范说类型是13sp或14sp,而前导(线高-同样)应为24dp。

这就是问题所在:这些开发人员告诉我,无法像代码中那样设置行高。相反,他们告诉我测量文本两行之间的距离,并给他们测量该距离-假设它是4dp。他们想要我们正在使用的每种样式的文本。

我们使用“草图> Zepelin流”作为规格。

对于我来说,能够创建带有24dp开头的13sp的字体样式(在代码中可以很容易地成为类/样式)对我来说似乎很奇怪,而不能设置开头,而是必须添加第三个度量来混合。在Sketch或Zepelin中,“线之间”没有这样的位置。

这真的是完成的方式吗,还是有设置线高的适当方法?

Answers:


81

我将从Android Developer的角度进行解释。

行高通常表示文本大小+“填充”顶部/底部。

因此,如果您的设计师将行高设置为19sp,文本大小为15sp,则意味着您需要具有额外的填充4sp。

19sp-15sp = 4sp。

要在布局中实现它,请使用lineSpacingExtra属性。

<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"
/>

实现线高的另一种方法是使用刻度。例如,1.2。这意味着间距是文本大小的120%。

在上面的示例中,行高为19sp,文本大小为15sp。如果我们将其转换成规模,它就会变成。

19/15 = 1.26

要在布局中实现它,请使用lineSpacingMultiplier属性。

<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"
/>

2
出色的回答
Vlad19年

6
我认为如果文本在两行或更多行中,则lineSpacingExtra应该为(19sp-15sp)/ 2 = 2sp。
AndroidRuntimeException

惊人的解释!
rohanpro

13

从API 28开始,我们现在有了lineHeight

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

如果您使用的是样式,请不要忘记删除该应用程序:

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

或在代码中

TextView.setLineHeight(@Px int)

1
我发现的甚至是Google设置Line Height的努力与设计中显示的不一致(例如,使用相同配置将HTML呈现给我的东西)-我有20sp textSize和24dp lineHeight,并且计算了fontHeight在TextView.setLineHeight()中实际上可以达到24sp,因此setLineHeight不会发生任何变化
kassim

删除应用程序前缀会产生错误:Attribute is missing the namespace prefix
IgorGanapolsky'1

1
@latsson等于app:lineHeightapi 21到api 27的等效项?
toobsco42

@ toobsco42如果您的compileSdkVersion至少为28,则可以使用它,我猜您有吗?
拉松

2
@latsson是的。但是在28以下的API级别上如何工作?
toobsco42

6

这是一种以编程方式执行此操作的方法。

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;
}

6
lineHeight = height * multiplier + extra

因此,如果将乘数设置为0,则行高可以与多余的行高相同。

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

0

我总是以编程方式进行操作:

float spc = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,6,r.getDisplayMetrics());
textView.setLineSpacing(spc, 1.5f);

另外,请阅读有关版式的材料设计指南。这对于获得最佳外观确实很有帮助。


-1

这是React Native的解决方案:添加一个调整行高的跨度 https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/views/text/CustomLineHeightSpan .java

我的设计同事过多地使用了线高,这种痛苦使它在应用内出租后永远看起来都不对。

我将计划制作一个自定义TextView类,该类采用XML的arg,然后将其发布在这里。


1
不是仅链接的答案。这是一个带有链接的答案。答案本质上是“添加可调整线高的跨度”
Wai Ha Lee
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.