style(ui): 播放页间距等宽 + 控制行上移 25 + 进度条重写
- 标题/歌手/专辑的间距统一为 10,视感更整齐 - 底部留白 70 -> 45(控制行上移 25) - 进度条改用 LayoutBuilder + Positioned 绝对宽度, 背景/缓冲/已播三层顺序明确,不再出现两端亮块
This commit is contained in:
+82
-65
@@ -308,7 +308,7 @@ class _PlayerPageState extends BaseState<PlayerPage> {
|
|||||||
Widget _buildMainPage(AudioService service, Song song, bool isPlaying) {
|
Widget _buildMainPage(AudioService service, Song song, bool isPlaying) {
|
||||||
return Padding(
|
return Padding(
|
||||||
// 顶部留 16:与 AppBar/指示器拉开距离,避免封面贴着顶部
|
// 顶部留 16:与 AppBar/指示器拉开距离,避免封面贴着顶部
|
||||||
padding: const EdgeInsets.fromLTRB(24, 16, 24, 0),
|
padding: const EdgeInsets.fromLTRB(24, 24, 24, 0),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
@@ -366,17 +366,17 @@ class _PlayerPageState extends BaseState<PlayerPage> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
const SizedBox(height: 2),
|
const SizedBox(height: 10),
|
||||||
Text(
|
Text(
|
||||||
song.artist,
|
song.artist,
|
||||||
style: TextStyle(fontSize: 14, color: Colors.grey[400]),
|
style: TextStyle(fontSize: 16, color: Colors.grey[300]),
|
||||||
maxLines: 1,
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
),
|
),
|
||||||
|
|
||||||
// ---- 信息区(专辑 / 目录)----
|
// ---- 信息区(专辑 / 目录)----
|
||||||
if (_album.isNotEmpty || _folder.isNotEmpty) ...[
|
if (_album.isNotEmpty || _folder.isNotEmpty) ...[
|
||||||
const SizedBox(height: 14),
|
const SizedBox(height: 10),
|
||||||
if (_album.isNotEmpty)
|
if (_album.isNotEmpty)
|
||||||
Text(
|
Text(
|
||||||
_album,
|
_album,
|
||||||
@@ -409,7 +409,8 @@ class _PlayerPageState extends BaseState<PlayerPage> {
|
|||||||
|
|
||||||
// ---- 控制 ----
|
// ---- 控制 ----
|
||||||
_buildControlButtons(service, song, isPlaying),
|
_buildControlButtons(service, song, isPlaying),
|
||||||
const SizedBox(height: 20),
|
// 底部多留 50px:控制行整体上移
|
||||||
|
const SizedBox(height: 45),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@@ -548,70 +549,86 @@ class _PlayerPageState extends BaseState<PlayerPage> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
height: 24,
|
height: 24,
|
||||||
child: Stack(
|
child: LayoutBuilder(
|
||||||
alignment: Alignment.centerLeft,
|
builder: (context, constraints) {
|
||||||
children: [
|
final width = constraints.maxWidth;
|
||||||
Container(
|
return Stack(
|
||||||
height: 3,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: Colors.grey[800],
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
FractionallySizedBox(
|
|
||||||
alignment: Alignment.centerLeft,
|
alignment: Alignment.centerLeft,
|
||||||
widthFactor: bufferProgress.clamp(0.0, 1.0),
|
children: [
|
||||||
child: Container(
|
// 背景轨道
|
||||||
height: 3,
|
Positioned(
|
||||||
decoration: BoxDecoration(
|
left: 0,
|
||||||
color: const Color(0xFF4A7A7A),
|
right: 0,
|
||||||
borderRadius: BorderRadius.circular(2),
|
top: 10.5,
|
||||||
),
|
child: Container(
|
||||||
),
|
height: 3,
|
||||||
),
|
decoration: BoxDecoration(
|
||||||
FractionallySizedBox(
|
color: Colors.grey[800],
|
||||||
alignment: Alignment.centerLeft,
|
borderRadius: BorderRadius.circular(2),
|
||||||
widthFactor: displayProgress.clamp(0.0, 1.0),
|
),
|
||||||
child: Container(
|
|
||||||
height: 3,
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
color: const Color(0xFFB8D4D0),
|
|
||||||
borderRadius: BorderRadius.circular(2),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Positioned.fill(
|
|
||||||
child: SliderTheme(
|
|
||||||
data: SliderTheme.of(context).copyWith(
|
|
||||||
trackHeight: 0,
|
|
||||||
activeTrackColor: Colors.transparent,
|
|
||||||
inactiveTrackColor: Colors.transparent,
|
|
||||||
thumbColor: Colors.transparent,
|
|
||||||
overlayColor: Colors.transparent,
|
|
||||||
thumbShape: const RoundSliderThumbShape(
|
|
||||||
enabledThumbRadius: 0,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Slider(
|
// 已缓冲
|
||||||
value: displayProgress.clamp(0.0, 1.0),
|
Positioned(
|
||||||
min: 0.0,
|
left: 0,
|
||||||
max: 1.0,
|
top: 10.5,
|
||||||
onChanged: (value) {
|
child: Container(
|
||||||
setState(() => _dragProgress = value);
|
width: width * bufferProgress.clamp(0.0, 1.0),
|
||||||
},
|
height: 3,
|
||||||
onChangeEnd: (value) {
|
decoration: BoxDecoration(
|
||||||
final newPosition = Duration(
|
color: const Color(0xFF4A7A7A),
|
||||||
milliseconds:
|
borderRadius: BorderRadius.circular(2),
|
||||||
(value * duration.inMilliseconds)
|
),
|
||||||
.round(),
|
),
|
||||||
);
|
|
||||||
service.seekTo(newPosition);
|
|
||||||
setState(() => _dragProgress = null);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
),
|
// 已播放
|
||||||
),
|
Positioned(
|
||||||
],
|
left: 0,
|
||||||
|
top: 10.5,
|
||||||
|
child: Container(
|
||||||
|
width:
|
||||||
|
width * displayProgress.clamp(0.0, 1.0),
|
||||||
|
height: 3,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: const Color(0xFFB8D4D0),
|
||||||
|
borderRadius: BorderRadius.circular(2),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned.fill(
|
||||||
|
child: SliderTheme(
|
||||||
|
data: SliderTheme.of(context).copyWith(
|
||||||
|
trackHeight: 0,
|
||||||
|
activeTrackColor: Colors.transparent,
|
||||||
|
inactiveTrackColor: Colors.transparent,
|
||||||
|
thumbColor: Colors.transparent,
|
||||||
|
overlayColor: Colors.transparent,
|
||||||
|
thumbShape: const RoundSliderThumbShape(
|
||||||
|
enabledThumbRadius: 0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
child: Slider(
|
||||||
|
value: displayProgress.clamp(0.0, 1.0),
|
||||||
|
min: 0.0,
|
||||||
|
max: 1.0,
|
||||||
|
onChanged: (value) {
|
||||||
|
setState(() => _dragProgress = value);
|
||||||
|
},
|
||||||
|
onChangeEnd: (value) {
|
||||||
|
final newPosition = Duration(
|
||||||
|
milliseconds:
|
||||||
|
(value * duration.inMilliseconds)
|
||||||
|
.round(),
|
||||||
|
);
|
||||||
|
service.seekTo(newPosition);
|
||||||
|
setState(() => _dragProgress = null);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
Reference in New Issue
Block a user