0

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(
    ...
    )
  }
}
whatwhatwhat
  • 1,991
  • 4
  • 31
  • 50

2 Answers2

0

Because build method should return Widget, not Future. Either use FutureBuilderor StreamBuilderfor such cases.

FutureBuilder

StreamBuilder

Autocrab
  • 3,474
  • 1
  • 15
  • 15
0

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();
  }
}
ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96