如何正确设置Android的行高?

Maj*_*Tom 51 android typography

我是一名UX架构师,与一群大多数初级的Android开发人员合作.我们在Android中正确设置行高问题.

我们使用Material Design规范作为我们应用的指南.特别是,您可以在此处查看线​​高规格:

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

我们以Body 2为例.规格说类型是13sp或14sp,领先(行高 - 相同的东西)应该是24dp.

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

我们使用Sketch> Zepelin流程进行规范.

这似乎很奇怪,我才能够创建一个字体的风格(这可以很容易地在代码类/风格)是13SP与24dp领先,而不能设置的领先,而是要一个第三的措施增加混合.Sketch或Zepelin中没有"行间线"这样的措施.

这真的是它的完成方式,还是有正确的方法来设置线高?

Ari*_*Roy 71

解决方案很简单.只需使用你的这两个属性TextView,lineSpacingExtralineSpacingMultiplier.

例如,

<TextView
    android:layout_width="match_parent"
    android:layout_height="80dp"
    android:lineSpacingMultiplier="2.5"
    android:lineSpacingExtra="6dp"/>
Run Code Online (Sandbox Code Playgroud)

编辑

这些仅用于控制线之间的间距而不是字符(也称为Kerning).要控制字符间距,您可以使用我创建的库,KerningViews.

编辑2

android:lineSpacingExtra行间添加实际的额外空间.你应该使用这个.为了给你更多的信息,我给你的android:lineSpacingMultiplier属性作为一个比例因子与高度TextView.

如果你想要15dp线之间的空间,使用android:lineSpacingExtra="15dp",你很高兴.


ald*_*dok 27

我将从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"
/>
Run Code Online (Sandbox Code Playgroud)

实现线高的另一种方法是使用比例.例如,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"
/>
Run Code Online (Sandbox Code Playgroud)

  • 我认为如果文本有两行或更多行,则 lineSpacingExtra 应该是 (19sp - 15sp) / 2 = 2sp。 (7认同)
  • 我在这里没有看到提到的一件事是,“lineSpacingMultipler”和“lineSpacingExtra”仅在相关文本在屏幕上显示为多行时才会出现。您可以看到文档中写着“该值不会应用于文本的最后一行”* 这对我们开发人员意味着什么;如果您的文本行只有一行或少于一行,这对您不起作用。 (3认同)
  • 精彩的答案 (2认同)

Mla*_*jac 25

lineHeight = height * multiplier + extra
Run Code Online (Sandbox Code Playgroud)

因此,如果您设置 multiplier = 0,那么您可以使 line-height 与额外的相同。

<TextView
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:textSize="14sp"
  android:lineSpacingMultiplier="0"
  android:lineSpacingExtra="24sp"
/>
Run Code Online (Sandbox Code Playgroud)

  • 缺点是这不适用于单行。 (8认同)

lat*_*son 7

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

<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:text="Lorem ipsum dolor sit amet"
app:lineHeight="50sp"/>
Run Code Online (Sandbox Code Playgroud)

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

<style name="H1">
    <item name="android:textSize">20sp</item>
    <item name="lineHeight">30sp</item>
</style>
Run Code Online (Sandbox Code Playgroud)

或在代码中

TextView.setLineHeight(@Px int)
Run Code Online (Sandbox Code Playgroud)

  • 我发现甚至 Google 设置 Line Height 的努力与设计中显示的内容不匹配(即使用相同的配置呈现的 HTML 内容)-我有 20sp textSize 和 24dp lineHeight 并且计算了 fontHeight在 TextView.setLineHeight() 实际上工作到 24sp 所以 setLineHeight 不会改变任何东西 (2认同)
  • @latsson api 21 到 api 27 上的 `app:lineHeight` 等效项是什么? (2认同)
  • @latsson 是的。但如果 API 级别低于 28,这会如何工作呢? (2认同)

mig*_*uel 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;
}
Run Code Online (Sandbox Code Playgroud)