Flutter 如何获取有状态小部件字段的值?

Flutter how to get the value of a stateful widget's field?

我有一个 Flutter 应用程序,它使用 BottomNavigationBar。我制作了一个名为 CustomBottomNavBar 的 class,它描述了我的 BottomNavigationBar。在那里,我有一个名为 currentIndex 的整数字段,它是导航栏上当前选定图标的索引。我想从我的 main.dart class 中获取此值以显示名为 tabs 的 list<Widget> 的第 indexth 元素,其中包含相关选项卡。

CustomNavigationBar class:

    class CustomBottomNavBar extends StatefulWidget {
      @override
      _CustomBottomNavBarState createState() => _CustomBottomNavBarState();
    }
    
    class _CustomBottomNavBarState extends State<CustomBottomNavBar> {
      int currentIndex = 0;
      @override
      Widget build(BuildContext context) {
        return SizedBox(
                  height: 50,
                              child: BottomNavigationBar(
                    type: BottomNavigationBarType.fixed,
                    selectedFontSize: 11,
                    unselectedFontSize: 11,
                    selectedItemColor: Colors.white,
                    backgroundColor: Colors.grey[850],
                    currentIndex: currentIndex,
                    items: <BottomNavigationBarItem>[
                      BottomNavigationBarItem(
                        activeIcon: Icon(Icons.home),
                        icon: Icon(
                          Icons.home,
                          color: currentIndex == 0 ? Colors.white : Colors.grey[500],
                        ),
                        title: Text(
                          "Home",
                          style: TextStyle(color: currentIndex == 0 ? Colors.white : Colors.grey[500]),
                        ),
                      ),
                      BottomNavigationBarItem(
                          activeIcon: Icon(Icons.explore),
                          icon: Icon(
                            Icons.explore,
                            color: currentIndex == 1 ? Colors.white : Colors.grey[500],
                          ),
                          title: Text(
                            "Explore",
                            style: TextStyle(color: currentIndex == 1 ? Colors.white : Colors.grey[500]),
                          )),
                      BottomNavigationBarItem(
                          activeIcon: Icon(Icons.subscriptions),
                          icon: Icon(Icons.subscriptions, color: currentIndex == 2 ? Colors.white : Colors.grey[500]),
                          title: Text(
                            "Subscriptions",
                            style: TextStyle(color: currentIndex == 2 ? Colors.white : Colors.grey[500]),
                          )),
                      BottomNavigationBarItem(
                          activeIcon: Icon(Icons.mail),
                          icon: Icon(
                            Icons.mail,
                            color: currentIndex == 3 ? Colors.white : Colors.grey[500],
                          ),
                          title: Text(
                            "Inbox",
                            style: TextStyle(color: currentIndex == 3 ? Colors.white : Colors.grey[500]),
                          )),
                      BottomNavigationBarItem(
                          activeIcon: Icon(Icons.video_library),
                          icon: Icon(
                            Icons.video_library,
                            color: currentIndex == 4 ? Colors.white : Colors.grey[500],
                          ),
                          title: Text(
                            "Library",
                            style: TextStyle(color: currentIndex == 4 ? Colors.white : Colors.grey[500]),
                          ))
                    ],
                    onTap: (int index) {
                      setState(() {
                        currentIndex = index;
                      });
                    },
                  ),
                );
      }

}

main.dart:

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {

  final List<Widget> tabs = [
    Center(child: Text("Home"),),
    Center(child: Text("Explore"),),
    Center(child: Text("Subscriptions"),),
    Center(child: Text("Inbox"),),
    Center(child: Text("Library"),),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home:  Scaffold(
            appBar: CustomAppBar(),
            body: tabs[2], //Here I would like to do something like tabs[customBottomNavBar.currentIndex]
            //),
            bottomNavigationBar: CustomBottomNavBar()),
    );
  }
}

在此声明式编程模式中,您不能向小部件提问。小部件必须启动操作。您可以做的一件事是为您的小部件提供一个函数来调用:

bottomNavigationBar: CustomBottomNavBar(
  onChange: (pageId) {
    print("we're at page $pageId now");
  }
)

一旦你编写了这段代码,当你在 onChange 上快速修复(IntelliJ 中的 Alt+Enter,VSCode 中的 Ctrl+.)时,它将创建具有正确的事件处理程序参数类型。稍后您可以在 CustomBottomNavBar 小部件代码中调用它。

您应该通过构造函数将您的值从 main 传递到 CustomNavigationBar,并将其作为局部变量访问。

这是一个资源: https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html

查看第二个示例,了解如何设置构造函数以及如何访问变量。 (widget.YOUR_VAR_NAME).

如果你想将数据从你的小部件中取出到 main 中,那么你可以执行以下操作: 1- 在您的小部件 class 中设置一个 getter 方法,该方法 returns 您想要的数据。 2- 将小部件的实例存储在主函数中,然后使用它来获取数据或将其视为小部件。

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  var myWidget = CustomBottomNavBar();
  final List<Widget> tabs = [
    Center(child: Text("Home"),),
    Center(child: Text("Explore"),),
    Center(child: Text("Subscriptions"),),
    Center(child: Text("Inbox"),),
    Center(child: Text("Library"),),
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home:  Scaffold(
            appBar: CustomAppBar(),
            body: tabs[2], //Here I would like to do something like tabs[myWidget.currentIndex]
            //),
            bottomNavigationBar: myWidget),
    );
  }
}

希望这能解决您的问题