I have a widget that is going to use the flutter_sound package to record audio: https://flutter-sound.canardoux.xyz/readme.html
I set up the stateless widget, then used Android Studio's context actions to convert it to a stateful one. Then, I added the await keyword to match this example from the documentation: https://flutter-sound.canardoux.xyz/tau_api_recorder_open_audio_session.html
Android studio then gave an error that said I needed to convert the widget's build function to an async function. When I did so (via the context action), it gave another error: '_MsgInputState.build' ('Future<Widget> Function(BuildContext)') isn't a valid override of 'State.build' ('Widget Function(BuildContext)')
class _MsgInputState extends State<MsgInput> {
final database = FirebaseDatabase.instance.reference();
final auth = AuthService();
@override
Future<Widget> build(BuildContext context) async { //error points to the 'build' keyword here
final messageDao = MessageDao(groupIDPath: widget.groupIDPath);
final groupChatRef = database.child('groupChats/0exUS3P2XKFQ007TIMmm'); //TODO: Remove hardcoded value
final messageController = TextEditingController();
var myRecorder = await FlutterSoundRecorder().openAudioSession();
@override
void dispose() {
myRecorder.closeAudioSession();
super.dispose();
}
return Scaffold(
...
)
}
}
CodePudding user response:
Because build method should return Widget, not Future. Either use FutureBuilderor StreamBuilderfor such cases.
CodePudding user response:
The main problem is you have incorrect structure for your StatefulWidget class. See https://docs.flutter.dev/development/ui/interactive for details.
It should be something like this (read the comments for reason):
class MsgInput extends StatefulWidget {
const MsgInput({Key? key}) : super(key: key);
@override
_MsgInputState createState() => _MsgInputState();
}
class _MsgInputState extends State<MsgInput> {
// declaration and initialization of variables
final messageDao = MessageDao(groupIDPath: widget.groupIDPath);
final groupChatRef = database.child('groupChats/0exUS3P2XKFQ007TIMmm'); //TODO: Remove hardcoded value
final messageController = TextEditingController();
late var myRecorder;
@override
void initState() {
super.initState();
// Or initilize variables with their own method, especially a future one.
initialize();
}
// build should return Widget
@override
Widget build(BuildContext context) {
// Do not place variables here because Flutter calls the build() method
// every time it needs to change anything in the view, and this
// happens surprisingly often.
// Return your widget, not future widget.
return Scaffold(
...
);
}
// dispose must be member of _MsgInputState.
@override
void dispose() {
myRecorder.closeAudioSession();
super.dispose();
}
// specific method to initialize variables.
void initialize() async {
myRecorder = await FlutterSoundRecorder().openAudioSession();
}
}
