I have read and understood a similar question posted here, but am having trouble applying it to my use case. I am new to Flutter and am creating an app that streams audio from a given URL using Ryan Heise's audio_service plugin. Using this plugin I instantiate an audioHandler immediately upon starting my app:
late AudioHandler audioHandler;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
final session = await AudioSession.instance;
await session.configure(const AudioSessionConfiguration.music());
audioHandler = await AudioService.init(
builder: () => AudioPlayerHandler(),
config: const AudioServiceConfig(
androidNotificationChannelId: 'com.ryanheise.myapp.channel.audio',
androidNotificationChannelName: 'Channel Name',
androidNotificationOngoing: true,
),
);
runApp(const MyApp());
}
With this audioHandler initialized, I would like to use it in child widgets. The example below demonstrates one such child widget:
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Koradi Radio",
theme: ThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: Colors.white70,
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
themeMode: ThemeMode.system,
home: const EnglishHome());
}
}
class EnglishHome extends StatefulWidget {
const EnglishHome({Key? key}) : super(key: key);
@override
_EnglishHomeState createState() => _EnglishHomeState();
}
class _EnglishHomeState extends State<EnglishHome> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('English Radio'),
backgroundColor: Colors.transparent,
),
body: ...
}
}
Note that MyApp currently just routes to EnglishHome(), but I plan on adding additional languages and instead routing MyApp to a page where a user can select their language. How can I pass audioHandler to all descendent widgets from Main()? (EnglishHome, EspHome, FrenchHome, etc?) Based upon what I have read, I will either be modifying the Key parameter of child widgets or else their BuildContext?
You can use provider
package and all you need to do is use Provider.value
and then use Provider.of(context)
in your EnglishHome
, FrenchHome
etc classes.
late AudioHandler audioHandler;
Future<void> main() async {
audioHandler = await AudioService.init(...);
runApp(MyApp(audioHandler));
}
class MyApp extends StatelessWidget {
final AudioHandler audioHandler;
const MyApp(this.audioHandler, {Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Provider.value(
value: audioHandler, // Providing the data above MaterialApp
child: MaterialApp(
home: EnglishHome(),
),
);
}
}
class EnglishHome extends StatelessWidget {
@override
Widget build(BuildContext context) {
// Accessing the data.
final audioHandler = Provider.of<AudioHandler>(context);
return Container();
}
}
The other answers here are also valid solutions, but what I was able to do was add an audioHandler parameter to EnglishHome:
class EnglishHome extends StatefulWidget {
var audioHandler;
EnglishHome({Key? key, this.audioHandler}) : super(key: key);
@override
_EnglishHomeState createState() => _EnglishHomeState();
And then pass the audioHandler in when the Widget was called from my main.dart file:
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
title: "Radio",
theme: ThemeData(
brightness: Brightness.light,
scaffoldBackgroundColor: Colors.blue[100],
),
darkTheme: ThemeData(
brightness: Brightness.dark,
),
themeMode: ThemeMode.system,
home: EnglishHome(
audioHandler: audioHandler,
));
}
}
You can do this with the provider plugin.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.