You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter报错:表达式类型为‘void’无法使用(音频播放器开发)

问题原因与解决方法

你遇到的错误是因为audioplayers库的API在近几年发生了重大更新——2020年的旧版本中,play()和pause()方法会返回状态码(比如1代表成功),但新版本里这两个方法的返回类型已经变成void,不再返回任何值,所以你不能将它们的返回值赋值给变量res,也没法用res==1来判断操作是否成功。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:audioplayers/audioplayers.dart';

class AudioPlayerPage extends StatefulWidget {
  const AudioPlayerPage({Key? key}) : super(key: key);

  @override
  State<AudioPlayerPage> createState() => _AudioPlayerPageState();
}

class _AudioPlayerPageState extends State<AudioPlayerPage> {
  final AudioPlayer audioPlayer = AudioPlayer();
  Duration duration = Duration.zero;
  Duration position = Duration.zero;
  bool playing = false;

  @override
  void initState() {
    super.initState();
    // 初始化时添加监听,避免每次点击都重复订阅
    _setupAudioListeners();
  }

  void _setupAudioListeners() {
    audioPlayer.onDurationChanged.listen((Duration dd) {
      setState(() {
        duration = dd;
      });
    });

    audioPlayer.onPositionChanged.listen((Duration dd) {
      setState(() {
        position = dd;
      });
    });

    // 监听播放完成事件,自动重置playing状态
    audioPlayer.onPlayerComplete.listen((_) {
      setState(() {
        playing = false;
        position = Duration.zero;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: [
          _slider(),
          InkWell(
            onTap: _togglePlayPause,
            child: Icon(
              playing ? Icons.pause : Icons.play_arrow,
              size: 50,
            ),
          )
        ],
      ),
    );
  }

  Widget _slider() {
    return Slider.adaptive(
      min: 0.0,
      value: position.inSeconds.toDouble(),
      max: duration.inSeconds.toDouble(),
      onChanged: (double value) {
        audioPlayer.seek(Duration(seconds: value.toInt()));
      },
    );
  }

  Future<void> _togglePlayPause() async {
    const url = "https://file-examples.com/storage/fe0b804ac5640668798b8d0/2017/11/file_example_MP3_700KB.mp3";

    if (playing) {
      await audioPlayer.pause();
      setState(() {
        playing = false;
      });
    } else {
      await audioPlayer.play(UrlSource(url));
      setState(() {
        playing = true;
      });
    }
  }

  @override
  void dispose() {
    audioPlayer.dispose(); // 销毁播放器,释放资源
    super.dispose();
  }
}

关键改动说明

  1. 移除res变量判断:直接调用pause()和play(),操作后通过setState更新playing状态,新版本API不需要依赖返回值判断操作结果。
  2. 优化监听逻辑:把音频时长、进度的监听移到initState中,避免每次点击播放按钮重复订阅事件,同时添加播放完成监听自动重置状态。
  3. 代码规范调整:将类名改为大驼峰命名(符合Dart规范),提取重复逻辑为单独方法,添加dispose方法销毁播放器避免内存泄漏。
  4. 使用Duration.zero替代空Duration:更符合Dart最佳实践。

内容的提问来源于stack exchange,提问作者Umer Yaseen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 22:35:00