注销阿里旗下的一个 App 之前我顺便看了下他们的淘宝 App,我的手机系统到晚上会自动切换到深色模式,晚上打开淘宝 App 它的界面是下图这样的。

It's about the network
深色模式时淘宝 App 的界面

左边和中间都是主界面的截图。顶部的“订阅”、“推荐”与背景颜色很接近,几乎融合到了一起;深色的“会员码”、搜索框都与浅色背景形成强烈而刺眼的对比,中间图搜索框右侧还有个浅色渐变填充,不知道怎么来的,左边的搜索按钮橙色而中间的搜索按钮却是灰色;下方的按钮栏紧挨着与底部系统导航栏,按钮栏高度与系统导航栏高度差不多,图标被紧紧的“压着”,我按“购物车”时应该要看着点以免按到“返回”。

左边内容板块的大黑框也与浅色背景形成强烈而刺眼的对比,“精选”下方的 Tab 指示器紧紧的挨着按钮文字,指示器颜色与文字颜色较接近,虽然是个指示器但是要稍加留意才能看到,上方右侧“+订阅”有个“X”,不知道是用来关闭什么的。中间内容板块上方的两排按钮文字接近背景色,和顶部的文字一样,像是背景的一部分,下方的展示内容看上去是由很多嵌着图案的黑白色块构成。

右边是设置界面截图。标题栏深色的返回箭头没有切换到深色模式该有的亮色;不知道列表有没用分隔线(Divider),反正看不到分隔线;列表条目右侧的浅色箭头的背景,在深色大背景里显得尤为刺眼,看上去也没切换到深色模式。

以上可以归纳为两点:深色模式问题,深色模式下界面的颜色显然已经错乱了;布局纵向密集,在 Tab 指示器和按钮栏布局中有所体现,过于密集的布局会增加操作的难度。两个问题先铺垫一下,后面还会再讲到。其他细节由于没有足够的信息,这里就不讲了。

再铺垫两个专业概念:适配,即对接系统、服务功能特性或是对接硬件设备的参数(如支持多种屏幕),使得 App 能够具备新的能力或是在不同的设备上运行;响应,侦听外部变化信号(如屏幕分辨率变化)并实时的处理,使得 App 能够在变化的环境中保持良好的状态。两者的主要区别是:适配是静态、一次性的,响应则是动态、连续的。App 做好适配并不难但是做好响应则比较难,因为后者需要 App 内部做大范围的支援,需要在开发之初就有良好的统筹和设计,要有架构思维。

总之,我个人是没法在深色模式下使用淘宝 App,其实这些都在预料之中,因为早前我已经从阿里旗下另外一个购物 App(下图)了解到了这些,从响应深色模式、响应屏幕变化、交互逻辑等方面大概的了解了它的开发水准。接下来就看看这个“金标认证”、“12亿下载量”的国际知名大厂 App,由于不想靠近这个 App,我不会提及这个 App 的名称并且尽量用“它”来代指

It's about the network
大厂 App

讲之前先交代一下背景,我尝试注销这个 App 时提示最近购物 15 天之后才能注销,于是我就计划十多天后再注销,看大厂 App 的内容是在等待注销的十多天时间里看的,估计看了有一二十次,每次几分钟到十几分钟不等,十多天时间里都让 App 保持更新并且删除数据,以避免旧版本数据产生影响,我手机的处理器是骁龙 865,算高性能级别的手机。

It's about the network
布局

我把上图注销界面的文本信息模糊掉了,以便于把注意力放到控件布局上。这个界面中间偏下有个“已阅并同意”单选按钮(RadioButton),下方紧挨着是“确定”按钮,再下方还有约占屏幕 30% 的可用空间。

普遍认知的界面交互里,单选按钮(RadioButton)是表达多选一而且必须有选择,复选框(CheckBox)是表达确认或不确认(你可以勾选或不选)。“已阅并同意”(表达确认)用单选按钮很少见,而且与人们已经建立的交互认知有冲突,规范的做法是用 CheckBox。

这个界面不管有没按“已阅并同意”,“确定”按钮一直都是可用的,但是逻辑上“不同意”则无法“确定”(可以直接返回),规范的做法是没按“已阅并同意”时“确定”按钮要置为不可点击的状态(Disabled),按了“已阅并同意”后“确定”按钮才能是可用状态(Enabled)。

正如前面提到的“纵向密集”问题,确切的说是它让我了解到大厂购物 App 的“纵向密集”风格,这个界面应该要细心才能点击到“已阅并同意”,不然就容易点到“确定”按钮。

It's about the network
深色模式

深色模式下打开 App 就这样,不过上面是它更早版本的截图不是最近的状态,最近看的时候深色模式问题已经没了,因为它不再支持“深色模式”,反正我没找到怎么切换,我任何时间打开它都是亮色的。与前面讲的淘宝深色模式如出一辙,我就不多讲了。

放弃“深色模式”的解决方案也合理,因为购物 App 势必会有大量的图片展示,不是所有的图片都能契合亮色模式又能契合深色模式,要处理好深色模式可能会有些麻烦,客户端甚至要引入图像处理,放弃这个特性不好的地方我觉得就是缺失大厂气质。

界面底部的“发闲置”按钮,后面的版本把图标换了但还是值得提一下。除了深色模式显示刺眼的白色背景外,按钮顶部锯齿一般的边缘也格外清楚,下面是原图的按钮部分(我的网页不对图片做放大处理)。

It's about the network
按钮边缘

这种锯齿很像以前 UI 贴图(位图)那时出现的状况,图片边缘不光滑显示出来就这样,此外,位图在被显示之前都需要进行插值(一般是由 GUI 引擎处理),以适应不同的尺寸的显示需要,图像放大(插值计算)时边缘锯齿也会更明显。

边缘生成阴影(Shadow)可以掩盖一下锯齿,不过会增加计算量,整个 App 会往“卡顿”方向走。使用矢量图是更好的做法,矢量图渲染根据目标分辨率直接计算生成图像,效果比贴图要好很多,由于没有繁重的插值计算,在大量图标的界面里用矢量图理论上响应速度会更快。

It's about the network
黑白

上面是要求网站、App 的主页面变黑白期间的截图,三个都是主界面,左边是黑白的,中间和右边的下半部分却是彩色的。同样的,打开它就这样。

注意三张图中间偏下 Tab 的文本,左边“猜你喜欢”、右边“BJD娃娃”是粗体字,而中间“鱼币抵钱”是常规字,为什么会这样呢?

It's about the network
分屏模式

登录界面,左边是正常状态右边(上方)是分屏状态,分屏时登录方式按钮栏层叠在界面中间的位置,底层(Layer)约一半的内容被盖住。分屏时底层可以 Scroll,我需要小心翼翼的 Scroll 底层的内容上来才能看到那个登录按钮,说小心翼翼是因为操作不能碰到顶层按钮栏。

它使用了 Flutter 框架,Flutter Activity 默认是注册侦听很多的外部变化事件如 UI 模式(深色模式切换)、分屏、屏幕旋转等等,同时也需要 App 能响应这些变化。

这个登录页面需要摆放 Widget(框架需要计算 Widget 的位置)又要整个页面能 Scroll,看起来有冲突,但还是有办法可以处理得更好。

It's about the network
交互逻辑

上面(右边)的状态不是打开就这样的,而是我操作几次屏幕旋转后进入分屏才变这样的。点击右上角的“More”按钮会在界面底部弹出“分享”对话框,然后就如展示的那样,底部只露出一个“分享”,看不到别的内容也没法操作。

此时,它的右侧边缘还出现一条竖着的白线,宽度大概几个象素,高度贯穿整个屏幕。由于没有多少信息,作为认同工程文化的开发者,我就不做揣测了。

It's about the network
闪烁

上面界面背景图为深色,透明的状态栏图标和文字也为深色,状态栏上除了右侧电池电量 48% 之外其他信息基本看不清。能看到电池电量是因为电池图标自带了背景,而不受状态栏背景以及 App 背景图的影响。

点击“奢侈箱包”后,首先,上方会刷出一块白色色块,色块高度刚到挡住文字,同时下方的“验货保真放心买”也消失,然后,白色色块消失,下方的“验货保真放心买”出现,整个 Table 栏(包含左侧箭头、文字按钮、右侧搜索、More按钮)都上移,上移约一行文本的高度,最后,Table 栏降下回到正常位置,Table Item 切换到“奢侈腕表”。

需要提一下的是,上面是它放弃深色模式并且经过多次更新后的情况。

It's about the network
输入框与代码版本管理

第一次进入客服界面是它更早的版本,上图左边和中间两个都是,底部是个输入框(Edit),当我点击输入内容时弹出的输入法层叠于界面之上,直接把界面的下半部分挡住了(上图中间),包括输入框。此时 Focus 还在输入框上,可以输入内容但是看不见自己输入了什么,也看不见对方刚刚回了什么。

看大厂 App 期间它这个界面更新过,更新后可以响应输入法事件,可以正常输入信息。但有意思的是,它更近的版本更新又把响应输入法问题给“改回”去了,即又是层叠于界面之上(上图右边)。

我相信它不是改回去的,而倾向于是代码版本管理方面的问题。

END

解开它 APK 可以找到“libflutter.so”文件,意味着它使用了 Flutter 框架,从默认支持(至少申明支持)屏幕旋转、分屏、深色模式来看的确如此。

不过,Flutter 骄傲原生跨平台它这我没看到,没见 Windows 端版本也没见 Web 端(非原生),对于内容展示型 App 一套代码跨平台并非难事;Flutter 骄傲的配色系统它这我没看到,对于现代 App 来说,深色模式应该是标配;Flutter 骄傲的动画渲染它这我没看到,印象中还有看到过“掉帧”的动画;Flutter 骄傲响应式布局支持它这很 Low,改进的话我觉得可以放弃支持分屏,屏幕旋转也可以拿掉。

最后我个疑问,它引以为傲的是什么?