首页 > 解决方案 > 颤振中的屏幕导航

问题描述

更新:

该应用程序有两个有状态的小部件屏幕:主页和搜索。两个屏幕都有搜索框和底部导航。

需要解决的问题是当用户点击主屏幕顶部的搜索框时,应用程序应该将他们带到搜索屏幕而不隐藏底部导航(就像 eBay 应用程序所做的那样)。

当用户点击主屏幕上的搜索框时,我尝试调用 Search 类。这种方法有效。但是,新屏幕隐藏了底部的导航栏。

以下代码处理屏幕之间的导航。

class Home extends StatefulWidget {
  @override
  _HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
  int _currentIndex = 0;
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Navigator(
          key: _navigatorKey,
          onGenerateRoute: (RouteSettings settings) {
            switch (settings.name) {
              case 'Search':
                return MaterialPageRoute(builder: (context) => Search());
              default:
                return MaterialPageRoute(builder: (context) => UserHome());
            }
          }),
       bottomNavigationBar: BottomNavigationBar(
        onTap: _onTap,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home),title: Text('Home'))
          BottomNavigationBarItem(icon: Icon(Icons.search), title: Text('Search'))
        ],
      ),
    );
  }

  void _onTap(int tappedIndex) {
    setState(() => _currentIndex = tappedIndex);
    switch (tappedIndex) {
      case 0:
        _navigatorKey.currentState.pushReplacementNamed('Home');
        break;
      case 1:
        _navigatorKey.currentState.pushReplacementNamed('Search');
        break;
    }
  }

}

标签: fluttersearchnavigation

解决方案


如果您尝试这样做以进行自动化测试。您可以使用小部件测试来做到这一点。Flutter 中的小部件测试可以模拟按钮点击并检查预期输出


class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  final GlobalKey<NavigatorState> _navigatorKey = GlobalKey<NavigatorState>();
  bool home;

  @override
  void initState() {
    super.initState();
    home = true;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: home ? UserHome() : Search(),
      bottomNavigationBar: BottomNavigationBar(
        onTap: _onTap,
        items: [
          BottomNavigationBarItem(icon: Icon(Icons.home), title: Text('Home')),
          BottomNavigationBarItem(
              icon: Icon(Icons.search), title: Text('Search'))
        ],
      ),
    );
  }

  void _onTap(int tappedIndex) {
    setState(() {
      if (tappedIndex == 0) {
        home = true;
      } else {
        home = false;
      }
    });
  }
}

class UserHome extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Center(
          child: Container(
            color: Colors.yellow,
            child: Text('USER HOME'),
          ),
        )
      ],
    );
  }
}

class Search extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Center(
          child: Container(
            color: Colors.green,
            child: Text('SEARCH'),
          ),
        )
      ],
    );
  }
}

我知道这与您的初始解决方案不太相似,但它实现了您想要的行为。


推荐阅读