style(ui): 播放页指示器改为"当前页长条"样式 + 补齐底部安全区

指示器(按设计稿):
- 三段:左点 / 中条 / 右点
- 当前页对应的段展开为 30x7 长条并高亮白色,
  另外两段收起为 7x7 小点(暗)
- 主页=中间长条,信息页=左长条,歌词页=右长条,220ms 动画过渡
- 点击任一段可直接跳到对应页

安全区:
- PageView 外层包 SafeArea(top: false),
  控制按钮不再贴着 mback 手势区
This commit is contained in:
2026-10-31 22:59:27 +08:00
parent 7cd1e13a82
commit abe960cf58
+31 -25
View File
@@ -249,21 +249,25 @@ class _PlayerPageState extends BaseState<PlayerPage> {
), ),
], ],
), ),
body: PageView( body: SafeArea(
controller: _pageController, top: false,
onPageChanged: (index) => setState(() => _pageIndex = index), child: PageView(
children: [ controller: _pageController,
_buildInfoPage(song), onPageChanged: (index) => setState(() => _pageIndex = index),
_buildMainPage(service, song, isPlaying), children: [
_buildLyricsPage(song), _buildInfoPage(song),
], _buildMainPage(service, song, isPlaying),
_buildLyricsPage(song),
],
),
), ),
); );
} }
/// 顶部两点指示器:左点=信息页,右点=歌词页,中间不亮表示在主页 /// 顶部指示器:当前页对应"长条",另外两页是小点。
/// 主页=中间长条,信息页=左长条,歌词页=右长条。
Widget _buildPageIndicator() { Widget _buildPageIndicator() {
Widget dot(int index) { Widget segment(int index) {
final active = _pageIndex == index; final active = _pageIndex == index;
return GestureDetector( return GestureDetector(
onTap: () => _pageController.animateToPage( onTap: () => _pageController.animateToPage(
@@ -271,13 +275,18 @@ class _PlayerPageState extends BaseState<PlayerPage> {
duration: const Duration(milliseconds: 280), duration: const Duration(milliseconds: 280),
curve: Curves.easeOutCubic, curve: Curves.easeOutCubic,
), ),
child: AnimatedContainer( behavior: HitTestBehavior.opaque,
duration: const Duration(milliseconds: 200), child: Padding(
width: 7, padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 2),
height: 7, child: AnimatedContainer(
decoration: BoxDecoration( duration: const Duration(milliseconds: 220),
shape: BoxShape.circle, curve: Curves.easeOutCubic,
color: active ? Colors.white : Colors.white24, width: active ? 30 : 7,
height: 7,
decoration: BoxDecoration(
color: active ? Colors.white : Colors.white24,
borderRadius: BorderRadius.circular(4),
),
), ),
), ),
); );
@@ -286,14 +295,11 @@ class _PlayerPageState extends BaseState<PlayerPage> {
return Row( return Row(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
dot(0), segment(0),
Container( const SizedBox(width: 6),
width: 56, segment(1),
height: 1, const SizedBox(width: 6),
margin: const EdgeInsets.symmetric(horizontal: 8), segment(2),
color: Colors.white12,
),
dot(2),
], ],
); );
} }