资讯专栏INFORMATION COLUMN

Android UI 文本还原纪实

番茄西红柿 / 2991人阅读

摘要:对于开发同学来说不管用户比例多高设计稿都按给绝对是最值得吐槽的事情之一在我刚开始接触开发的那个阶段每当有人问起这件事我都说的做法就是看着差不多就行了后来有些要求特别高的设计开发同学就只能很苦逼的一个一个的改到满意为止我看现在不少辅助开发工具

对于 Android 开发同学来说, "不管用户比例多高, 设计稿都按 iOS 给"绝对是最值得吐槽的事情之一.

在我刚开始接触 Android 开发的那个阶段, 每当有人问起这件事, 我都说 "Android 的做法就是看着差不多就行了..." 后来有些要求特别高的设计, Android 开发同学就只能很苦逼的一个 dp 一个 dp 的改到 UI 满意为止. 我看现在不少辅助开发工具的思路也是这样.

17 年底 ~ 18 年初搞 UI 大改版的时候, iOS 开发同学 传人 Joe 跟设计敲定了 iOS 的还原方式. 我觉得如果 Android 不搞的话之后开发就太烦了, 就决定 试一试. 最后的方案虽然不是特别通用, 但也能解决大部分问题.

然后就被设计小姐姐催着写原理, 然后一年就过去了...


从这里开始

上图中, 粉底的 "22 一行"和 "22 多行"是设计小姐姐给的参照图, 是用 Sketch 输出的, 使用 22 号字+默认行高情况下的设计稿上的样子. 绿底和黄底的 "22 一行"是 Nexus 5 上, 使用 22dp 的样子; 蓝底(叠加显示成紫色)的 "22 四行"也是 22dp, 文字用 " " 换行. 底色之间的差异就是"行高"的差异.

可见绿底一行的行高有一点细微的偏差, 黄底一行因为叠加了 4 次这个误差, 比较明显. 多行情况下的误差更大, 因为 Android 和 iOS 在多行文本排版的概念上差异很大. 参照图上单行和多行是能对上的, 现在我们要想办法让 Android 的单行和多行都能跟参照图对上.

单行对齐

观察发现单行差的是底部的一段空白, 我称之为 additionalPaddingBottom. 对比各种字号的情况, 发现并没有规律, 因此搞出来一组经验值.

这个经验值在 3 倍屏上还是比较准确的(最重要的是设计走查就用 3 倍屏...), 单行文字位置和行高都能对上. 在其他倍数的屏幕上基本 ok, 但也有一些异常. 比如在 1.5 倍屏上, 部分字号只能达成行高对的上但文字位置对不上的效果, 而且还受到 setSingleLine 的影响, 15dp + setSingleLine(true) 时偏差尤其大.

/** * density 为 3 时的经验值, 作为计算 additionalLineSpace 的基数 */ static { paddingBottomMap.put(10, 1f / 3); paddingBottomMap.put(11, 4f / 3); paddingBottomMap.put(12, 2f / 3); paddingBottomMap.put(13, 1f / 3); paddingBottomMap.put(14, 3f / 3); paddingBottomMap.put(15, 2f / 3); paddingBottomMap.put(16, 1f / 3); paddingBottomMap.put(17, 4f / 3); paddingBottomMap.put(19, 1f / 3); paddingBottomMap.put(22, 2f / 3); paddingBottomMap.put(30, 5f / 3); }

多行对齐

根据 Android 文本排版概念, 我写了个简单的 MetricsTextView 来确定单行和多行的行高关系:

观察发现: 两行文字的高度 = 单行文字的高度 + 单行文字设置 setIncludeFontPadding(false) 的高度

同时, 两行文字和两组单行的差别在于文字之间的空白, 因此需要增加 lineSpaceExtra = topSpace + bottomSpace + additionalPaddingBottom. 这样 Android 也实现了 n 行文字行高 = n x 单行文字行高, 多行也就对上了.

行高

上面都是参考图使用默认行高的情况, 如果行高变了呢);

/** * sketch 中字号对应的默认行高 (dp) */ static { defaultLineHeightMap.put(10, 14); defaultLineHeightMap.put(11, 16); defaultLineHeightMap.put(12, 17); defaultLineHeightMap.put(13, 18); defaultLineHeightMap.put(14, 20); defaultLineHeightMap.put(15, 21); defaultLineHeightMap.put(16, 22); defaultLineHeightMap.put(17, 24); defaultLineHeightMap.put(19, 26); defaultLineHeightMap.put(30, 42); }

首先我们有默认行高的值, 然后把 deltaPaddingTop = deltaPaddingBottom = (lineHeight - defaultLineHeight) / 2 用 paddingTop 和 paddingBottom 加到 每一行 上 - 实验结果表明上下加的一样多, 可以除 2, 真是幸运.

带行高的对齐:

局限性

只关注行高, 不关注文本宽度, 所以换行还是跟 iOS 不一样.

并不是对所有的字号/字体都有效, 只处理了我们常用的字号(其它字号要加也不难), 默认字体.

没有抽成库, 原因就是上面那条.

18 年 Android 最新的 support 库好像为 AppCompatTextView 增加了行高支持, 但我还没有来得及试.

其它已知问题

5.0 以下系统需要特殊处理 paddingBottom, 因为会增加额外的 lineSpaceExtra

但是有些 5.0 及以上的手机 (vivo X9, 锤子) 居然也有这个问题, 管不了了...

因为直接修改了 TextView 的 paddingTop 和 paddingBottom, 如果设计稿上有上下边距, 只能用 margin 或者再嵌套一层的方式解决.

也许可以写得更完善些.

在生产环境中使用时, 有同学发现该 TextView 中 ClickableSpan 的点击事件无法被触发.

还木有解决...

@Uraka.Lee

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/7064.html

相关文章

  • Android UI 文本还原纪实

    摘要:对于开发同学来说不管用户比例多高设计稿都按给绝对是最值得吐槽的事情之一在我刚开始接触开发的那个阶段每当有人问起这件事我都说的做法就是看着差不多就行了后来有些要求特别高的设计开发同学就只能很苦逼的一个一个的改到满意为止我看现在不少辅助开发工具对于 Android 开发同学来说, 不管用户比例多高, 设计稿都按 iOS 给绝对是最值得吐槽的事情之一. 在我刚开始接触 Android 开发的那个阶...

    gxyz 评论0 收藏0
  • SharedPreference 简介

    摘要:能够保存一组原始数据的名值对保存为命名的首选项。对于不同的屏幕尺寸版本,用于显示头及其相关的布局也可能不同。因此,当设备配置改变,并且被销毁和重新创建时,的和不会被调用。 SharedPreference SharedPreference 当存储 UI 状态、用户首选项、应用程序设置时,我们需要一种轻量级机制以存储一个已知的值集。SharedPreference 能够保存一组原始数据...

    wzyplus 评论0 收藏0
  • 洞察数据价值——第十二期魅族技术开放日现场纪实

    摘要:月日,由魅族科技联合麦思博有限公司主办的第十二期魅族技术开放日洞察数据价值在深圳虚拟大学园触梦社区顺利举行。活动现场,名大数据技术开发从业者齐聚一堂。图片描述图片描述以上为本期魅族技术开放日分享内容的简要介绍。 3月31日,由魅族科技联合麦思博(msup)有限公司主办的第十二期魅族技术开放日洞察数据价值在深圳虚拟大学园触梦社区顺利举行。珠三角特区宝贵的科技资源与精准的技术从业人群为本次...

    jimhs 评论0 收藏0
  • 今年最新的30个Android库,你了解吗?

    摘要:本文就向大家介绍今年最新的深受开发者喜爱的个库。目前提供的功能有和三个位置的吸附指定要分屏的数量,支持水平和垂直分屏,滚动时的回调。只能包含一个子布局,例如,,,等。项目的简介写得很好,易于理解。 Android开发技术越来越成熟,Android开发工具当然也层出叠现。本文就向大家介绍今年最新的深受开发者喜爱的30个Android库。希望对你的Android开发工作能起到助力。 1.M...

    KevinYan 评论0 收藏0
  • Qcon 演讲纪实:详解如何在实时视频通话中实现AR功能

    摘要:声网首席研发工程师,端移动应用产品设计和技术架构负责人龚宇华,受邀分享了基于和,在实时视频通话中实现功能,在演讲中剖析了与差异,的工作原理,以及逐步讲解如何基于与声网创建视频会议场景。实现视频通话功能我们可以通过声网来快速实现视频通话。 2018年4月20日-22日,由 infoQ 主办的 Qcon 2018全球软件开发大会在北京如期举行。声网首席 iOS 研发工程师,iOS 端移动应...

    gitmilk 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<