使用 Flutter 和 'flutter_fft' 插件创建吉他调音器,努力将 BottomNavigationBar 包含在调音器的 Stateful Widget 中

Creating a guitar tuner using Flutter and 'flutter_fft' plugin, struggling to include BottomNavigationBar with the Tuner's Stateful Widget

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

我想包括一个 BottomNavigationBar 以在这三个工具之间导航,每个工具占用一页。我可以在使用 StatelessWidget 时让导航正常工作,但是一旦我开始使用 _TunerState 进行录制,我就开始收到错误消息。

我仅使用 main.dart 就设法让这个工具在单独的应用程序中工作,但事实证明将该解决方案集成到我的项目中很困难。

我打算做的是使用 _TunerState class 初始化并启动 flutter_fft 记录器 ,它会监听麦克风输入和输出信息的变化,如频率、音符等

下面是我的 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 等

提前致谢,非常感谢任何帮助,或者任何关于更好方法的建议肯定也会有帮助:)

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