大多数应用的底栏只是排着几个标签的固定盒子。做 Yoin 时,我把导航和迷你播放器揉进了一根浮动栏里:首页和资料库守在两边,正在播的歌夹在中间。点一下中央胶囊,播放页向上撑开;点开专辑,详情页从上方滑入;侧滑返回把上层页面拉走,这根底栏依然稳稳停在原处。
想让它看起来轻轻松松地待在原地,底下却得解开一连串相当拧巴的布局与窗口难题。
三个按钮的宽度守恒
最初我直接用了 Material 3 Expressive 的官方按钮组组件。按住任何一个按钮,它会向外鼓起,旁边的按钮跟着收窄让位,整排按钮摸起来很有弹性。
结果这个官方组件在折叠屏上崩了。在 Pixel Fold 内屏展开正在播放页时,转场中途传进去的极端尺寸让组件算出了负数宽度,直接抛了 Android 布局异常。
没办法,只能甩开官方组件自己重写整条底栏,亲手算按压形变。第一版我不小心把正负号写反了,按钮一按反而往里缩,跟 Expressive 的手感完全拧着来;改对之后,按左右导航键时按钮向外撑开,多出的宽度由中间的曲目胶囊吸收;按住中央胶囊,两边按钮就一块儿往外退。
导航的四种形态
这根底栏其实一直在换造型。没播歌的时候,中间的胶囊完全收起,首页和资料库向中间拉宽,露出文字标签;歌一响,曲目胶囊就挤进它们中间;点进专辑页,首页和资料库收成 0,原地长出这张专辑的“播放”分体按钮;到了平板的双列画面上,导航、曲目胶囊和专辑按钮干脆一字排开。
最早其实还有第五种造型:没播歌时中间也留着空胶囊,点进去是一整页空荡荡的“未在播放”。后来干脆把空槽折起来,这个多余的空页面也就一起砍掉了。
曲目切入的方向感
切到下一首歌时,上一首的歌名往左快速闪开,新歌名从右边顺着空间弹簧推入,停稳前带一点轻微的回弹。在 Yoin 的其他地方,我们也保留了这种简单的骄傲的「安卓感」。
两个独立窗口,同一根底栏
在手机竖屏这种单列画面下,为了用上 Android 14+ 原生的跨 Activity 预测性返回——也就是手指往回滑时,底下能直接露出真实的首页——专辑、艺术家和播放列表详情页其实都跑在各自独立的窗口里。问题是,Android 的两个窗口之间根本没法共享任何视图,连底栏也不行。
我们的障眼法,是在两个窗口完全相同的屏幕坐标上,各画一根逐像素对齐的底栏。点开专辑的那一刻,底下窗口的底栏原地开始变形,上层专辑窗口同时淡入,由另一根位置分毫不差的底栏接手。侧滑返回时,只有上层页面跟着手指往边上缩,底栏钉在原地,随着你的手势倒着变回原来的模样。
手指还在屏幕上时,所有形变都跟手指位移 1:1 咬合,不加一点滤波或延迟;直到你松手的那一瞬间,才交给弹簧收尾。
宽屏下的同窗合体
到了平板或展开的折叠屏上,详情页不再另开新窗口,而是直接从同一个窗口的右边滑进来。这时底栏会横跨左右两栏:左边管首页和资料库,中间是能伸缩的正在播放胶囊,右边直接长出这张专辑的播放与随机播放按钮。关掉右栏时,右边那组按钮又顺着同一套槽位插值,折回胶囊里去。
隐形的基准线
折腾这么多,其实只是为了让你在听歌时根本不用分神去想底栏在哪儿。无论页面如何推入、分列或撤回,它始终安静地停在拇指下方。但每次当你通过不同方式返回时,你一定会感受到我们用心的设计。