【问题标题】:Cupertino Tab Bar库比蒂诺标签栏
【发布时间】:2021-10-01 05:04:54
【问题描述】:

我正在尝试实现 Cupertino 底部标签栏。我有2个问题。当我在 Cupertino 选项卡视图中调用 widgetBuilder 时,我得到“无法无条件调用该函数,因为它可以为 'null'”,所以添加一个空检查“!”但它需要另一个。

然后,当我尝试使用 currentTab、onSelectTab、widgetBuilder 作为字段返回 CupertinoHomeScaffold 时,它说参数“key”是必需的。不知道该怎么办。

如果你看到任何东西,请告诉我!提前谢谢..!

        import 'package:flutter/cupertino.dart';
        import 'package:flutter/material.dart';
        
        enum TabItem { jobs, entries, account }
        
        class TabItemData {
          const TabItemData({required this.title, required this.icon});
        
          final String title;
          final IconData icon;
        
          static const Map<TabItem, TabItemData> allTabs = {
            TabItem.jobs: TabItemData(title: 'Jobs', icon: Icons.work),
            TabItem.entries: TabItemData(title: 'entries', icon: Icons.view_headline),
            TabItem.account: TabItemData(title: 'entries', icon: Icons.person),
          };
        }
        
        class HomePage extends StatefulWidget {
          @override
          _HomePageState createState() => _HomePageState();
        }
        
        class _HomePageState extends State<HomePage> {
          TabItem _currentTab = TabItem.jobs;
        
          Map<TabItem, WidgetBuilder> get widgetBuilder {
            return {
              TabItem.jobs: (_) => Container(),
              TabItem.entries: (_) => Container(),
              TabItem.account: (_) => Container(),
            };
          }
        
          void _select(TabItem tabItem) {
            setState(() => _currentTab = tabItem);
          }
        
          @override
          Widget build(BuildContext context) {
            return CupertinoHomeScaffold(
              currentTab: _currentTab,
              onSelectTab: _select,
              widgetBuilder: widgetBuilder,
            );
          }
        }
        
        class CupertinoHomeScaffold extends StatelessWidget {
          const CupertinoHomeScaffold({
            required Key key,
            required this.currentTab,
            required this.onSelectTab,
            required this.widgetBuilder,
          }) : super(key: key);
        
          final TabItem currentTab;
          final ValueChanged<TabItem> onSelectTab;
          final Map<TabItem, WidgetBuilder> widgetBuilder;
        
          @override
          Widget build(BuildContext context) {
            return CupertinoTabScaffold(
              tabBar: CupertinoTabBar(
                items: [
                  _buildItem(TabItem.jobs),
                  _buildItem(TabItem.entries),
                  _buildItem(TabItem.account),
                ],
                onTap: (index) => onSelectTab(TabItem.values[index]),
              ),
              tabBuilder: (context, index) {
                final item = TabItem.values[index];
                return CupertinoTabView(
                  builder: (context) => widgetBuilder![item](context),
                );
              },
            );
          }
        
          BottomNavigationBarItem _buildItem(TabItem tabItem) {
            final itemData = TabItemData.allTabs[tabItem];
            return BottomNavigationBarItem(
              icon: Icon(itemData!.icon),
              label: itemData.title,
            );
          }
        }

【问题讨论】:

    标签: flutter tabbar flutter-cupertino


    【解决方案1】:

    key 设为可为空的变量:

    Key? key,
    

    对于widgetBuilder,您需要将!放在]之后:

    widgetBuilder[item]!(context),
    

    工作示例

    import 'package:flutter/cupertino.dart';
    import 'package:flutter/material.dart';
    
    void main() => runApp(
          MaterialApp(
            home: HomePage(),
          ),
        );
    
    enum TabItem { jobs, entries, account }
    
    class TabItemData {
      const TabItemData({required this.title, required this.icon});
    
      final String title;
      final IconData icon;
    
      static const Map<TabItem, TabItemData> allTabs = {
        TabItem.jobs: TabItemData(title: 'Jobs', icon: Icons.work),
        TabItem.entries: TabItemData(title: 'entries', icon: Icons.view_headline),
        TabItem.account: TabItemData(title: 'entries', icon: Icons.person),
      };
    }
    
    class HomePage extends StatefulWidget {
      @override
      _HomePageState createState() => _HomePageState();
    }
    
    class _HomePageState extends State<HomePage> {
      TabItem _currentTab = TabItem.jobs;
    
      Map<TabItem, WidgetBuilder> get widgetBuilder {
        return {
          TabItem.jobs: (_) => Container(),
          TabItem.entries: (_) => Container(),
          TabItem.account: (_) => Container(),
        };
      }
    
      void _select(TabItem tabItem) {
        setState(() => _currentTab = tabItem);
      }
    
      @override
      Widget build(BuildContext context) {
        return CupertinoHomeScaffold(
          currentTab: _currentTab,
          onSelectTab: _select,
          widgetBuilder: widgetBuilder,
        );
      }
    }
    
    class CupertinoHomeScaffold extends StatelessWidget {
      const CupertinoHomeScaffold({
        Key? key,
        required this.currentTab,
        required this.onSelectTab,
        required this.widgetBuilder,
      }) : super(key: key);
    
      final TabItem currentTab;
      final ValueChanged<TabItem> onSelectTab;
      final Map<TabItem, WidgetBuilder> widgetBuilder;
    
      @override
      Widget build(BuildContext context) {
        return CupertinoTabScaffold(
          tabBar: CupertinoTabBar(
            items: [
              _buildItem(TabItem.jobs),
              _buildItem(TabItem.entries),
              _buildItem(TabItem.account),
            ],
            onTap: (index) => onSelectTab(TabItem.values[index]),
          ),
          tabBuilder: (context, index) {
            final item = TabItem.values[index];
            return CupertinoTabView(
              builder: (context) => widgetBuilder[item]!(context),
            );
          },
        );
      }
    
      BottomNavigationBarItem _buildItem(TabItem tabItem) {
        final itemData = TabItemData.allTabs[tabItem];
        return BottomNavigationBarItem(
          icon: Icon(itemData!.icon),
          label: itemData.title,
        );
      }
    }
    

    【讨论】:

    • 很高兴能为您提供帮助。如果您认为此答案解决了您的问题,您能否将此答案标记为已接受?
    • 嘿!我曾尝试 +1,但不能因为我没有足够的积分(我是新人)。我还有另一个(小)问题。使用这种结构,当我在第一页时,当我弹出上下文时,我会收到一条错误消息,所以你知道另一种方法可以在不返回 Cupertino 的情况下弹回日志屏幕吗?
    • 支持是不同的。您可以通过点击“复选标记”来接受答案。
    • 你能举一个新问题的例子吗?我不明白弹出问题。
    • 所以基本上,在 HomePage 类中,Cupertino 是用 _currentTab = TabItem.jobs 实现的,其中路由转到 First_page。但是我在第一页上创建了一个 log_out 功能,它会弹出上下文。因此,当我尝试注销并返回时,我会在第一页上显示红色屏幕,但 CupertinoScaffold 的另一个选项卡看起来不错。
    猜你喜欢
    • 2021-03-29
    • 2021-10-12
    • 1970-01-01
    • 2019-08-05
    • 2020-08-24
    • 1970-01-01
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多