【问题标题】:How can I stop radio stream when navigating in Flutter?在 Flutter 中导航时如何停止广播流?
【发布时间】:2020-06-26 20:24:08
【问题描述】:

我正在开发这个目前可以运行的颤振无线电流应用程序。我正在使用AnimatedIcons.play_pause 来启动和停止无线电流。目前,如果我导航到另一个页面,流将继续播放。当我导航到另一个页面时,我想停止流式传输(不使用暂停按钮)。原因是当您返回流媒体页面时...页面已重置回播放按钮bool isPlaying = false; 但流仍处于开启状态,因此按下播放按钮将播放 2 个流。

下面是完整的代码:

import 'dart:async';
import 'package:flutter_radio/flutter_radio.dart';

void main() => runApp(HarvestRadio());

class HarvestRadio extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<HarvestRadio>
    with SingleTickerProviderStateMixin {
  String url = "https://fm898.online/mystream.mp3";

  AnimationController _animationController;

  bool isPlaying = false;

  @override
  void initState() {
    super.initState();
    audioStart();
    _animationController =
        AnimationController(vsync: this, duration: Duration(milliseconds: 300));
  }

  @override
  void dispose() {
    super.dispose();
    _animationController.dispose();
  }

  Future<void> audioStart() async {
    await FlutterRadio.audioStart();
    print('Audio Start OK');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Harvest Radio Online',
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(
            title: const Text('Harvest Radio Online '),
            backgroundColor: Colors.blue,
            centerTitle: true,
          ),
          body: Container(
            color: Colors.blueGrey.shade900,
            child: Column(
              children: <Widget>[
                Expanded(
                  flex: 7,
                  child: Icon(
                    Icons.radio, size: 250,
                    color: Colors.lightBlue,
                  ),
                ),
                Material(
                  color: Colors.blueGrey.shade900,
                  child: Center(
                    child: Ink(
                      decoration: const ShapeDecoration(
                        color: Colors.lightBlue,
                        shape: CircleBorder(),
                      ),
                      child: IconButton(
                        color: Colors.blueGrey.shade900,
                        iconSize: 67,
                        icon: AnimatedIcon(
                          icon: AnimatedIcons.play_pause,
                          progress: _animationController,
                        ),
                        onPressed: () => _handleOnPressed(),
                      ),
                    ),
                  ),
                ),
                SizedBox(height: 50,)

              ],
            ),
          ),
        ));
  }

  void _handleOnPressed() {
    setState(() {
      FlutterRadio.play(url: url);
      isPlaying = !isPlaying;
      isPlaying
          ? _animationController.forward()
          : _animationController.reverse();
    });
  }
}

非常感谢任何帮助...谢谢!

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    我也遇到过类似的情况,最终扩展了routeObserver 以随时了解用户状态:

    routeObserver.dart:

    import 'package:flutter/material.dart';
    
    class RouteObserverUtil extends RouteObserver<PageRoute<dynamic>> {
      RouteObserverUtil({this.onChange});
      final Function onChange;
      void _sendScreenView(PageRoute<dynamic> route) {
        String screenName = route.settings.name;
        onChange(screenName);
      }
    
      @override
      void didPush(Route<dynamic> route, Route<dynamic> previousRoute) {
        super.didPush(route, previousRoute);
        if (route is PageRoute) {
          _sendScreenView(route);
        }
      }
    
      @override
      void didReplace({Route<dynamic> newRoute, Route<dynamic> oldRoute}) {
        super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
        if (newRoute is PageRoute) {
          _sendScreenView(newRoute);
        }
      }
    
      @override
      void didPop(Route<dynamic> route, Route<dynamic> previousRoute) {
        super.didPop(route, previousRoute);
        if (previousRoute is PageRoute && route is PageRoute) {
          _sendScreenView(previousRoute);
        }
      }
    }
    

    这是一个用法示例:

    import 'package:flutter/material.dart';
    import 'package:flutter/scheduler.dart';
    
    import 'package:myApp/utils/routeObserver.dart';
    
    class _RouterScreenState extends State<RouterScreen> {
      RouteObserverUtil _routeObserver;
    
      @override
      void initState() {
        super.initState();
        _routeObserver = RouteObserverUtil(onChange: _onChangeScreen);
      }
    
      void _onChangeScreen(String screen) {
        SchedulerBinding.instance.addPostFrameCallback((_) {
          print("changed to screen: " + screen);
        });
      }
    
      ...
    
    }
    

    【讨论】:

      【解决方案2】:

      我找到了一个简单的解决方案,用WillPopScope 包裹我的MaterialApp ...这是代码:

        Widget build(BuildContext context) {
          return WillPopScope(
            onWillPop: _onBackPressed,
            child: MaterialApp(
                title: 'Harvest Radio Online',
                home: Scaffold(
                  appBar: AppBar(
                    title: const Text('Harvest Radio Online '),
                    backgroundColor: Colors.blue,
                    centerTitle: true,
                  ),
      
      

      然后是_onBackPressed的函数:

      Future<bool>_onBackPressed(){
          FlutterRadio.stop();
          Navigator.pop(
              context, MaterialPageRoute(builder: (_) => Media()));
        }
      

      我还必须将 Navigator 路由添加回上一页。

      我知道这有点小技巧,但它确实有效。谢谢大家!

      【讨论】:

        猜你喜欢
        • 2016-12-24
        • 1970-01-01
        • 2021-08-26
        • 2019-06-01
        • 2016-03-30
        • 1970-01-01
        • 1970-01-01
        • 2016-04-28
        • 1970-01-01
        相关资源
        最近更新 更多