1

我正在开发一个颤振应用程序,当用户从剩余的 BottomNavigationBar 屏幕的任何其他屏幕按下返回时,我需要重定向到 BottomNavigationBar 上的第一个屏幕。现在,我在一个简单的按钮上添加了重定向事件,将在_onWillPop事件中替换它。

请在下面找到代码:

class HomeScreen extends StatefulWidget {
  @override
  _HomeScreenState createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {

  final PageStorageBucket bucket = PageStorageBucket();

  Widget currentScreen = HomeFragment();
  int currentTab = 0;

  static int selectedIndexN = 0;
  static const TextStyle optionStyle = TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
  List<Widget> _widgetOptions1 = <Widget>[
    HomeFragment(),
    LoginFargment(),
    SignUpFargment(),
    ProfileFargment(),
  ];

  void changeTabMethod(int index) {
    print('changeTabMethod is called');
    setState(() {
      selectedIndexN = index;
    });
    print('changeTabMethod is called : selectedIndexN : $selectedIndexN');
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      // return GetBuilder<DashboardController>(
      body: Center(
        child: _widgetOptions1.elementAt(selectedIndexN),
      ),
      bottomNavigationBar: BottomNavigationBar(
        type: BottomNavigationBarType.fixed,
        currentIndex: selectedIndexN,
        onTap: changeTabMethod,
        items: const <BottomNavigationBarItem>[
          BottomNavigationBarItem(
            icon: Icon(Icons.home),
            label: 'Home',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.business),
            label: 'Login',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'SignUp',
          ),
          BottomNavigationBarItem(
            icon: Icon(Icons.school),
            label: 'Profile',
          ),
        ],
      ),
    );
  }
}

配置文件屏幕代码:

class ProfileFargment extends StatefulWidget {
  @override
  _ProfileFragmentState createState() => _ProfileFragmentState();
}

class _ProfileFragmentState extends State<ProfileFargment> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body:SafeArea(
          child: Container(
            padding: EdgeInsets.all(20.0),
            height: double.infinity,
            width: double.infinity,
            color: Colors.teal,
            child: GestureDetector(
                  onTap: () {
                    //Calling method changeTabMethod(0)
                    HomeScreen().createState().changeTabMethod(0);
                  },
                  child: Container(
                    margin: EdgeInsets.only(top: 20.0),
                    height: 40.0,
                    width: 150.0,
                    color: Colors.white,
                    child: Center(child: Text('Profile'),),
                  ),
                ),
        ),
      ),
    );
  }
}

另一方面,当我changeTabMethod从 ProfileFragment 屏幕调用时,它将进入changeTabMethod但无法执行 setState 方法。所以我的标签没有改变。

您可以考虑此控制台报告: changeTabMethod is called仅在setState未执行后打印第二次打印。

你能告诉我我做错了什么或在哪里做错了吗?

提前致谢 :-)

4

2 回答 2

1

这实际上很简单,您只需要将函数传递给子小部件。

因此,您ProfileFragment将采用一个名为changeTabtype的变量Function(int)

Function(int) changeTab;
ProfileFragment(this.changeType); // Constructor

当您在内部创建小部件时,您将其传递_HomeScreenState

List<Widget> _widgetOptions1 = <Widget>[
  …
  ProfileFargment(changeTabMethod),
];

然后你可以直接在里面调用函数_ProfileFragmentState

onTap: () => widget.changeTab(0);
于 2021-05-22T22:45:29.120 回答
1

试试下面的代码。通过将函数作为参数传递,您可以从任何其他页面触发主页上的函数。主屏幕代码:

 class HomeScreen extends StatefulWidget {
      @override
      _HomeScreenState createState() => _HomeScreenState();
    }
    
    class _HomeScreenState extends State<HomeScreen> {
      final PageStorageBucket bucket = PageStorageBucket();
    
    //       Widget currentScreen = HomeFragment();
      int currentTab = 0;
    
      static int selectedIndexN = 0;
      static const TextStyle optionStyle =
          TextStyle(fontSize: 30, fontWeight: FontWeight.bold);
    
      Widget _widgetOptions1(int index) {
        switch (index) {
          case 0:
            return ProfileFargment(onButtonPressed: changeTabMethod);
    
          case 1:
            return Container(child: Text("Page - 2 "));
    
          case 2:
            return Container(child: Text("Page - 3 "));
          default:
            return Container();
        }
      }
    
      void changeTabMethod(int index) {
        print('changeTabMethod is called');
        setState(() {
          selectedIndexN = index;
        });
        print('changeTabMethod is called : selectedIndexN : $selectedIndexN');
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          // return GetBuilder<DashboardController>(
          body: Center(
            child: _widgetOptions1(selectedIndexN),
          ),
          bottomNavigationBar: BottomNavigationBar(
            type: BottomNavigationBarType.fixed,
            currentIndex: selectedIndexN,
            onTap: changeTabMethod,
            items: const <BottomNavigationBarItem>[
              BottomNavigationBarItem(
                icon: Icon(Icons.home),
                label: 'Home',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.business),
                label: 'Login',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.school),
                label: 'SignUp',
              ),
              BottomNavigationBarItem(
                icon: Icon(Icons.school),
                label: 'Profile',
              ),
            ],
          ),
        );
      }
    }

配置文件屏幕代码:

class ProfileFargment extends StatefulWidget {
  final void Function(int) onButtonPressed;
  const ProfileFargment({Key key, this.onButtonPressed});
  @override
  _ProfileFragmentState createState() => _ProfileFragmentState();
}

class _ProfileFragmentState extends State<ProfileFargment> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          padding: EdgeInsets.all(20.0),
          height: double.infinity,
          width: double.infinity,
          color: Colors.teal,
          child: GestureDetector(
            onTap: () {
              //Calling method changeTabMethod(0)
              // HomeScreen().createState().changeTabMethod(0);
              widget.onButtonPressed(0);
            },
            child: Container(
              margin: EdgeInsets.only(top: 20.0),
              height: 40.0,
              width: 150.0,
              color: Colors.white,
              child: Center(
                child: Text('Profile'),
              ),
            ),
          ),
        ),
      ),
    );
  }
}
于 2021-05-28T07:41:25.367 回答