在屏幕之间导航时布尔值被重置

问题描述 投票:0回答:1

我正在尝试使用 flutter 创建一个收音机播放器应用程序。该应用程序只有 2 个屏幕,可通过 BottomNavigationBar(在本例中为 GNav)访问。

当我开始听广播时,播放按钮变成了暂停按钮。现在,当通过 BottomNavBar 切换屏幕然后再次返回播放器时,正在运行的广播播放器现在有一个播放按钮,而不是预期的暂停按钮,因为音频仍在播放。

当我开始听广播时,播放按钮变成了暂停按钮。现在,当通过 BottomNavBar 切换屏幕然后再次返回播放器时,正在运行的广播播放器现在有一个播放按钮,而不是预期的暂停按钮,因为音频仍在播放。

我很确定每次切换屏幕时都会调用

bool isPlaying = false;

我该怎么做才能使

bool isPlaying
每次回到播放器时都不会重置为“假”?

main.dart:

import 'package:flutter/material.dart';
import 'package:radio_orient/components/bottom_nav_bar.dart';
import 'package:radio_orient/pages/home.dart';
import 'package:radio_orient/pages/more_info.dart';

void main() {
  runApp(RadioApp());
}

class RadioApp extends StatefulWidget {
  @override
  _RadioAppState createState() => _RadioAppState();
}

class _RadioAppState extends State<RadioApp> {
  int _selectedIndex = 0;

  void navigateBottomBar(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  final List<Widget> _pages = [Home(), const MoreInfo()];

  @override
  void initState() {
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('Radio Orient'),
          backgroundColor: Color.fromARGB(255, 36, 120, 85),
        ),
        body: _pages[_selectedIndex],
        backgroundColor: const Color.fromRGBO(207, 185, 151, 1),
        bottomNavigationBar: MyBottomNavBar(
          onTabChange: (index) => navigateBottomBar(index),
        ),
      ),
    );
  }
}

home.dart:

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

class Home extends StatefulWidget {
  Home({
    super.key,
  });

  @override
  State<Home> createState() => _HomeState();
}

class _HomeState extends State<Home> {
  RadioPlayer _radioPlayer = RadioPlayer();
  List<String>? metadata;
  bool isPlaying = false;

  void initRadioPlayer() {
    _radioPlayer.setChannel(
      title: 'My Radio',
      url:
          'https://myradio.url',
      imagePath: 'assets/radio.jpg',
    );

    _radioPlayer.stateStream.listen((value) {
      setState(() {
        isPlaying = value;
      });
    });

    _radioPlayer.metadataStream.listen((value) {
      setState(() {
        metadata = value;
      });
    });
  }

  @override
  void initState() {
    super.initState();
    initRadioPlayer();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          FutureBuilder(
            future: _radioPlayer.getArtworkImage(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              Image artwork;
              if (snapshot.hasData) {
                artwork = snapshot.data;
              } else {
                artwork = Image.asset(
                  'assets/radio.jpg',
                  fit: BoxFit.cover,
                );
              }
              return SizedBox(
                height: 180,
                width: 180,
                child: ClipRRect(
                  child: artwork,
                  borderRadius: BorderRadius.circular(15.0),
                ),
              );
            },
          ),
          const SizedBox(height: 20),
          const Text(
            'Radio Orient Live',
            softWrap: false,
            overflow: TextOverflow.fade,
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24),
          ),
          Text(
            metadata?[1] ?? '',
            softWrap: false,
            overflow: TextOverflow.fade,
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          SizedBox(height: 20),
          FloatingActionButton(
            onPressed: () {
              isPlaying ? _radioPlayer.pause() : _radioPlayer.play();
            },
            tooltip: 'Control button',
            child: Icon(
              isPlaying ? Icons.pause_rounded : Icons.play_arrow_rounded,
            ),
          ),
        ],
      ),
    );
  }
}

bottom_nav_bar.dart:

import "package:flutter/material.dart";
import "package:google_nav_bar/google_nav_bar.dart";

class MyBottomNavBar extends StatelessWidget {
  void Function(int)? onTabChange;
  MyBottomNavBar({super.key, required this.onTabChange});

  @override
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.symmetric(vertical: 20),
      child: GNav(
        color: Colors.grey.shade400,
        activeColor: Colors.grey.shade700,
        tabActiveBorder: Border.all(color: Colors.white),
        tabBackgroundColor: Colors.grey.shade100,
        mainAxisAlignment: MainAxisAlignment.center,
        tabBorderRadius: 16,
        onTabChange: (value) => onTabChange!(value),
        tabs: [
          GButton(
            icon: Icons.home,
            text: 'Start',
          ),
          GButton(
            icon: Icons.info,
            text: 'Info',
          )
        ],
      ),
    );
  }
}
flutter dart
1个回答
0
投票

问题是,当您切换屏幕时,

state
会从树中删除。因此,要说 flutter 保持活动状态,您可以使用 mixin:
AutomaticKeepAliveClientMixin
那么您的主屏幕将如下所示:

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

class Home extends StatefulWidget {
  Home({
    super.key,
  });

  @override
  State<Home> createState() => _HomeState();
}

// add this mixin to your state definition
class _HomeState extends State<Home> with AutomaticKeepAliveClientMixin {
  RadioPlayer _radioPlayer = RadioPlayer();
  List<String>? metadata;
  bool isPlaying = false;

  // here you say that this state should be keept alive
  @override
  bool get wantKeepAlive => true;

  void initRadioPlayer() {
    _radioPlayer.setChannel(
      title: 'My Radio',
      url:
          'https://myradio.url',
      imagePath: 'assets/radio.jpg',
    );

    _radioPlayer.stateStream.listen((value) {
      setState(() {
        isPlaying = value;
      });
    });

    _radioPlayer.metadataStream.listen((value) {
      setState(() {
        metadata = value;
      });
    });
  }

  @override
  void initState() {
    super.initState();
    initRadioPlayer();
  }

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          FutureBuilder(
            future: _radioPlayer.getArtworkImage(),
            builder: (BuildContext context, AsyncSnapshot snapshot) {
              Image artwork;
              if (snapshot.hasData) {
                artwork = snapshot.data;
              } else {
                artwork = Image.asset(
                  'assets/radio.jpg',
                  fit: BoxFit.cover,
                );
              }
              return SizedBox(
                height: 180,
                width: 180,
                child: ClipRRect(
                  child: artwork,
                  borderRadius: BorderRadius.circular(15.0),
                ),
              );
            },
          ),
          const SizedBox(height: 20),
          const Text(
            'Radio Orient Live',
            softWrap: false,
            overflow: TextOverflow.fade,
            style: TextStyle(fontWeight: FontWeight.bold, fontSize: 24),
          ),
          Text(
            metadata?[1] ?? '',
            softWrap: false,
            overflow: TextOverflow.fade,
            style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 16),
          ),
          SizedBox(height: 20),
          FloatingActionButton(
            onPressed: () {
              isPlaying ? _radioPlayer.pause() : _radioPlayer.play();
            },
            tooltip: 'Control button',
            child: Icon(
              isPlaying ? Icons.pause_rounded : Icons.play_arrow_rounded,
            ),
          ),
        ],
      ),
    );
  }
}

这里的文档:点击我

© www.soinside.com 2019 - 2024. All rights reserved.