I am trying to display a list of files for playback and would like to allow the user to listen to them while selecting. I am using a DropdownButton to display the optional files. When the list is closed and i hit the play/stop icon, the icon is updated and displays correctly according to the state (playing/stopped). When the list is open the state is toggled but the icon doesnt get updated in the open list. How can i achieve this? I have tried using DropdownButton2 package. It is slightly better, it does updated the icon in the selected line but not next to any of the open items in the list.
import 'package:flutter/material.dart';
class SampleItemListView extends StatefulWidget {
const SampleItemListView({super.key,});
static const routeName = '/';
@override
State<StatefulWidget> createState() => SampleItemListViewState();
}
class SampleItemListViewState extends State<SampleItemListView> {
final List<String> items = const ['10', '20', '30'];
bool isPlaying = false;
String selectedItem = '10';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample Items'),
),
body: DropdownButtonFormField(
value: selectedItem,
onChanged: (value) async {
selectedItem = value.toString();
},
items: items
.map((e) => DropdownMenuItem(
value: e,
child: SizedBox(
width: 100,
child: Row(
children: [
IconButton(
onPressed: () async {
setState(() {
isPlaying = !isPlaying;
});
},
icon: isPlaying ?
const Icon(Icons.stop_circle) :
const Icon(Icons.play_arrow)),
const Spacer(),
Expanded(child: Text(e.toString())),
]
)
)))
.toList(),
),
);
}
}
You can use StatefulBuilder
because it has a own state and you can rebuild their local state
class SampleItemListView extends StatefulWidget {
const SampleItemListView({
super.key,
});
static const routeName = '/';
@override
State<StatefulWidget> createState() => SampleItemListViewState();
}
class SampleItemListViewState extends State<SampleItemListView> {
final List<String> items = const ['10', '20', '30'];
bool isPlaying = false;
String selectedItem = '10';
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Sample Items'),
),
body: DropdownButtonFormField(
value: selectedItem,
onChanged: (value) async {
selectedItem = value.toString();
},
items: items
.map((e) => DropdownMenuItem(
value: e,
/// You can use StatefulBuilder
child: StatefulBuilder(builder: (context, menuState) {
return SizedBox(
width: 100,
child: Row(children: [
IconButton(
onPressed: () async {
menuState(() {
isPlaying = !isPlaying;
});
},
icon: isPlaying ? const Icon(Icons.stop_circle) : const Icon(Icons.play_arrow)),
const Spacer(),
Expanded(child: Text(e.toString())),
]));
})))
.toList(),
),
);
}
}