【问题标题】:Is it possible to use a bottomNavBar for mobile and a Sidebar for desktop in flutter?是否可以在 flutter 中将 bottomNavBar 用于移动设备,将 Sidebar 用于桌面?
【发布时间】:2023-01-23 21:12:09
【问题描述】:

我目前正在开发一个跨平台应用程序,我想在其中使用侧边栏在桌面和平板电脑视图上进行导航,但在移动设备上使用底部导航栏,因为在移动设备上使用侧边栏并不是很方便。 我在导航部分遇到了问题,至于侧边栏,我可以轻松地使用 push() 函数。但是对于 bottomNavBar 我必须使用带有索引等的 onItemTapped 函数。有没有一种简单的方法可以一起使用它们/在它们之间切换?

这是我的边栏导航:

@override
  Widget build(BuildContext context) {
    return ListTile(
      onTap: () {
        Navigator.push(
          context,
          MaterialPageRoute(builder: (context) => page),
        );
      },

这就是我尝试进行 bottomNavBar 导航的方式:

currentIndex: _selectedIndex,
        onTap: _onItemTapped,
      ),
      body: PageNavigationItem.items.elementAt(_selectedIndex),
    );
  } // build method

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

【问题讨论】:

  • 如果 (Platform.isAndroid || Platform.isIos) showBottomNav, 否则 showSideBar

标签: flutter dart navigation sidebar flutter-bottomnavigation


【解决方案1】:

据我所知,除非您“制作自己的底部导航栏”,否则无法解决您的问题。

但是,我会问您是否不想使用 Drawer widget 而不是底部导航栏,因为这是一种让您的应用程序跨平台保持一致的方法,遵循项目的 flutter 指南并允许您使用推送。从某种意义上说,它是一个“侧边栏”。

如果我觉得我无论如何都需要它,我会做我自己的底部导航栏,像这样:

import 'package:flutter/material.dart';

class BottomNavigationBarWidget extends StatelessWidget {
  final List<Widget> children;
  final Widget body;
  const BottomNavigationBarWidget({Key? key, required this.children, required this.body}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(child: body),
        Row(
          mainAxisAlignment: MainAxisAlignment.spaceEvenly,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: children,
        )
      ],
    );
  }
}

在主页上有这个 类 MyHomePage 扩展 StatelessWidget { const MyHomePage({Key?key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Flutter app'),
      ),
      body: BottomNavigationBarWidget(
        body: Center(
          child: Text('Hello world!'),
        ),
        children: [
          Column(children:[Icon(Icons.percent), Text("Test")])
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          print('Zapp!');
        },
        backgroundColor: Colors.yellow[700],
        child: Icon(
          Icons.bolt,
          color: Colors.black,
        ),
      ),
    );
  }
}

这是结果

但说真的,使用 Drawer widget 更容易也更好

【讨论】:

    【解决方案2】:

    是的,这是可能的,一旦检查下面的示例代码。

    有关其工作原理的视频。https://drive.google.com/file/d/1BxK6qevJOu4qYrmnoTXdIYtqLAVC87ya/view?usp=share_link

    在这里,我们正在为 Title 和 onTap 创建一个模型

    class DataModel {
      final String labelName;
      final Function onTap;
      const DataModel({required this.labelName, required this.onTap});
    }
    

    在这里,我们正在创建一个 DataModel 列表,因此将在 Title 和 onTap 中使用。

    List<DataModel> dataList = [
        DataModel(
            labelName: "First",
            onTap: () {
              print("first");
            }),
        DataModel(
            labelName: "Second",
            onTap: () {
              print("Second");
            }),
        DataModel(
            labelName: "Third",
            onTap: () {
              print("Third");
            }),
        DataModel(
            labelName: "Fourth",
            onTap: () {
              print("Fourth");
            }),
      ];
    

    获取设备的功能是手机或平板电脑

    getDevice() {
        return MediaQuery.of(context).size.width <= 800 ? "Mobile" : "Tablet";
      }
    

    这是该页面的完整代码。

    class MyHomePage extends StatefulWidget {
      const MyHomePage({
        super.key,
      });
      @override
      State<MyHomePage> createState() => _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text("Demo Home Page"),
          ),
          drawer: getDevice() == "Tablet"
              ? Drawer(
                  child: ListView.builder(
                  itemCount: dataList.length,
                  itemBuilder: (context, index) {
                    return ListTile(
                      title: Text(dataList[index].labelName),
                      onTap: () {
                        dataList[index].onTap();
                      },
                    );
                  },
                ))
              : null,
          bottomNavigationBar: getDevice() == "Mobile"
              ? BottomNavigationBar(
                  onTap: (value) {
                    dataList[value].onTap();
                  },
                  // backgroundColor: Colors.black,
                  items: dataList.map((e) => BottomNavigationBarItem(backgroundColor: Colors.black, icon: Icon(Icons.add), label: e.labelName)).toList(),
                  // items: <BottomNavigationBarItem>[
                  //   BottomNavigationBarItem(label: "Test", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test1", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test2", icon: Icon(Icons.add)),
                  //   BottomNavigationBarItem(label: "Test3", icon: Icon(Icons.add)),
                  // ],
                )
              : null,
          body: Center(
            child: TextButton(
                onPressed: () {
                  setState(() {
                    // isHide = !isHide;
                  });
                },
                child: Text("Hide")),
          ),
        );
      }
    

    我希望这些东西能解决你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多