2

正如标题所提到的,我目前正在创建一个吉他应用程序,其中包括一些关于基本音符和和弦的信息、一个和弦发生器,当然还有一个吉他调音器。我决定从我认为最困难的部分开始,不幸的是几乎没有进展。

我想包含一个BottomNavigationBar来在这三个工具之间导航,每个工具都占用一页。我可以在使用StatelessWidget时让导航工作,但是一旦我开始使用_TunerState进行记录,我就会开始收到错误。

我已经设法让这个工具在一个单独的应用程序中工作,只使用main.dart,但是将该解决方案集成到我的项目中是很困难的。

我打算做的是使用_TunerState类来初始化和启动flutter_fft 录音机,它将监听 mic 输入和输出信息的变化,例如频率、音符等。

下面是我的 home_widget.dart,负责导航,或者至少这就是我试图用它做的事情

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State {
  int currentTab = 0;

  late Widget currentPage;
  late Fretboard fretboard;
  late ChordGen chordGen;
  late Tuner tuner;

  late List<Widget> pages;

  @override
  void initState() {

    fretboard = Fretboard();
    chordGen = ChordGen();
    tuner = Tuner();

    pages = [fretboard, chordGen, tuner];

    currentPage = fretboard;

    super.initState();

  }

  @override
   Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        systemOverlayStyle: SystemUiOverlayStyle(statusBarColor: Colors.transparent),
        toolbarHeight: -24,
      ),
      body: currentPage,
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: currentTab,
        onTap: (int index) {
          setState(() {
            currentTab = index;
            currentPage = pages[index];
          });
        },
        items: <BottomNavigationBarItem>[
          BottomNavigationBarItem(
              icon: Icon(GuitarIcons.two_music_notes, size: 30),
              title: Text("Fretboard")),
          BottomNavigationBarItem(
              icon: Icon(GuitarIcons.generator, size: 30),
              title: Text("Generator")),
           BottomNavigationBarItem(
              icon: Icon(GuitarIcons.sound_bars, size: 30),
              title: Text("Tuner")),
        ],
      ),
    );
  }
} 

这是我的 tuner.dart,它需要是有状态的,比如 flutterFft.onRecorderStateChange.listen

class Tuner extends StatefulWidget {
@override
_TunerState createState() => _TunerState();
}

class _TunerState extends State<Home> {
  double? frequency;

  String? note;

  int? octave;

  bool? isRecording;

  FlutterFft flutterFft = FlutterFft();

  _initialize() async {
    print("Starting recorder...");
    // print("Before");
    // bool hasPermission = await flutterFft.checkPermission();
    // print("After: " + hasPermission.toString());

    // Keep asking for mic permission until accepted
    while (!(await flutterFft.checkPermission())) {
      flutterFft.requestPermission();
      // IF DENY QUIT PROGRAM
    }

    // await flutterFft.checkPermissions();
    await flutterFft.startRecorder();
    print("Recorder started...");
    setState(() => isRecording = flutterFft.getIsRecording);

    flutterFft.onRecorderStateChanged.listen(
            (data) => {
          print("Changed state, received: $data"),
          setState(
                () => {
              frequency = data[1] as double,
              note = data[2] as String,
              octave = data[5] as int,
            },
          ),
          flutterFft.setNote = note!,
          flutterFft.setFrequency = frequency!,
          flutterFft.setOctave = octave!,
          print("Octave: ${octave!.toString()}"),
          sleep(const Duration(milliseconds: 100))
        },
        onError: (err) {
          print("Error: $err");
        },
        onDone: () => {print("Isdone")});
  }

  @override
   void initState() {
    isRecording = flutterFft.getIsRecording;
    frequency = flutterFft.getFrequency;
    note = flutterFft.getNearestNote;
    octave = flutterFft.getOctave;
    super.initState();
    _initialize();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: "Simple flutter fft example",
        theme: ThemeData.dark(),
        color: Colors.blue,
        home: Scaffold(
          backgroundColor: Colors.purple,
          body: Center(
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                isRecording!
                    ? Text("Current note: ${note!}",
                    style: TextStyle(fontSize: 30))
                    : Text("Not Recording", style: TextStyle(fontSize: 35)),
                isRecording!
                    ? Text(
                    "Current frequency: ${frequency!.toStringAsFixed(2)}",
                    style: TextStyle(fontSize: 30))
                    : Text("Not Recording", style: TextStyle(fontSize: 35))
              ],
            ),
          ),
        ));
       }
     }

因此,当我尝试在我的 Android 模拟器上运行应用程序时,我会收到此错误消息

======== Exception caught by widgets library =======================================================
The following assertion was thrown building _BodyBuilder:
StatefulWidget.createState must return a subtype of State<Tuner>

The createState function for Tuner returned a state of type _TunerState, which is not a 
subtype of State<Tuner>, violating the contract for createState.
The relevant error-causing widget was: 
  Scaffold Scaffold:file:///C:.../guitar_app/lib/home_widget.dart:42:12
When the exception was thrown, this was the stack: 
**followed by nearly 200 lines of error code....**

我在网上环顾四周,似乎找不到任何适合这个问题的东西,但也许当我看到它时我只是不知道答案....

如果需要更多信息,请告诉我,但希望我已将所有内容都包含在此处。我对 Flutter 很陌生,但了解大多数其他典型语言,即 Java、JS、Python、HTML 等。

在此先感谢,非常感谢任何帮助,或者任何关于更好方法的建议肯定也会有所帮助:)

4

1 回答 1

1

在您的 tuner.dart 文件中,_TurnerState extends the Sate<Home>但它需要扩展例如class _TunerState extends State<Turner>.

于 2021-12-29T21:41:27.967 回答